2008-09-24 25 views
18

tengo un cuadro de lista donde los elementos contienen casillas de verificación:WPF ListBoxItem problema de selección

<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

El problema que estoy teniendo es que cuando hago clic en la casilla de verificación o de su contenido, el ListBoxItem padre no ser seleccionado. Si hago clic en el espacio en blanco junto a la casilla de verificación, se selecciona ListBoxItem.

El comportamiento que intento obtener es poder seleccionar uno o varios elementos de la lista y usar la barra espaciadora para activar y desactivar las casillas de verificación.

algo más de información:

private void Checkbox_Click(object sender, RoutedEventArgs e) 
{ 
    CheckBox chkBox = e.OriginalSource as CheckBox; 
} 

En el código anterior cuando hago clic en una casilla de verificación, e.Handled es falsa y chkBox.Parent es nulo.

respuesta de Kent me puso por el camino correcto, esto es lo que terminó con:

<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox" PreviewKeyDown="ListBox_PreviewKeyDown"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" /> 
       <TextBlock Text="{Binding DisplayText}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

tuve que usar PreviewKeyDown porque por defecto cuando se pulse la barra espaciadora en un cuadro de lista, se anula la selección de todo a excepción de el elemento seleccionado más recientemente.

Respuesta

10

Para empezar, poner el contenido fuera de la CheckBox:

<StackPanel Orientation="Horizontal"> 
    <CheckBox IsChecked="{Binding IsChecked}"/> 
    <TextBlock Text="{Binding DisplayText}"/> 
</StackPanel> 

Después de eso, usted tendrá que asegurarse de que el espacio de prensado en un ListBoxItem resultados en la CheckBox que se comprueba. Hay varias formas de hacerlo, incluido un controlador de eventos simple en el ListBoxItem. O bien, podría especificar un controlador para UIElement.KeyUp o lo que sea en su DataTemplate:

<CheckBox IsChecked="{Binding IsChecked}" UIElement.KeyUp="..."/> 
3

También puede enlazar la propiedad IsChecked de la casilla de verificación y propiedad IsSelected del ListBoxItem:

<ListBox> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding DisplayText}" IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+1

Así lo hice al principio. El error es que los estados de la casilla de verificación están vinculados al estado de selección de control de lista, que no es el comportamiento normal para un control de lista que contiene casillas de verificación. –

2

En el caso de uso se sería mucho más simple usar un ItemsControl en lugar de un cuadro de lista. Un ItemsControl es similar a un Listbox, excepto que no contiene el comportamiento de selección automática. Lo que significa que usarlo para alojar una lista de lo que son esencialmente casillas de verificación es muy simple y no es necesario resolver el comportamiento de selección de ListBox.

simplemente cambiando a ItemsControl le dará exactamente lo que necesita:

<ItemsControl Style="{StaticResource CheckBoxListStyle}" Name="EditListBox"> 
    <ItemsControl .ItemTemplate> 
     <DataTemplate> 
      <CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Puede hacer clic en el texto para comprobar casillas de verificación (comportamiento por defecto) y se puede utilizar el teclado también sin tener que cablear los controladores de eventos .