wpf listbox

Problema de selección de WPF ListBoxItem



(3)

También puede enlazar la propiedad IsChecked de la propiedad CheckBox y IsSelected de ListBoxItem:

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

Tengo un cuadro de lista donde los elementos contienen casillas de verificació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 tengo es que cuando hago clic en la casilla de verificación o su contenido, el ListBoxItem principal no se selecciona. 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 en 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 falso y chkBox.Parent es nulo.

La respuesta de Kent me puso en el camino correcto, aquí es a lo que terminé:

<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 de forma predeterminada, cuando presionas la barra espaciadora en un cuadro de lista, anula la selección de todo excepto del elemento seleccionado más recientemente.


Para empezar, coloque el contenido fuera de CheckBox :

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

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

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


En su caso de uso, sería mucho más simple usar un ItemsControl 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 cambiar 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 marcar las casillas de verificación (comportamiento predeterminado) y también puede usar el teclado sin tener que conectar ningún controlador de eventos.