WPF ListBoxItem selection problem

17 of 26 picture 17 of 26 · Sep 24, 2008 · Viewed 21k times · Source

I have a listbox where the items contain checkboxes:

<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>

The problem I'm having is that when I click on the checkbox or its content, the parent ListBoxItem does not get selected. If I click on the white space next to the checkbox, the ListBoxItem does get selected.

The behavior that I'm trying to get is to be able to select one or many items in the list and use the spacebar to toggle the checkboxes on and off.

Some more info:

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

In the code above when I click on a checkbox, e.Handled is false and chkBox.Parent is null.

Kent's answer put me down the right path, here's what I ended up with:

<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>

I had to use PreviewKeyDown because by default when you hit the spacebar in a list box, it deselects everything except for the most recently selected item.

Answer

Kent Boogaart picture Kent Boogaart · Sep 24, 2008

To begin with, put the content outside the CheckBox:

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

After that, you will need to ensure that pressing space on a ListBoxItem results in the CheckBox being checked. There are a number of ways of doing this, including a simple event handler on the ListBoxItem. Or you could specify a handler for UIElement.KeyUp or whatever in your DataTemplate:

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