Подтвердить что ты не робот

Задача выбора WPF ListBoxItem

У меня есть список, в котором элементы содержат флажки:

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

Проблема, с которой я столкнулась, заключается в том, что когда я нажимаю на флажок или его содержимое, родительский ListBoxItem не выбирается. Если я нажимаю на пробел рядом с этим флажком, ListBoxItem действительно выбирается.

Поведение, которое я пытаюсь получить, - это выбрать один или несколько элементов в списке и использовать пробел для включения и выключения флажков.

Дополнительная информация:

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

В приведенном выше коде, когда я нажимаю на флажок, e.Handled является false и chkBox.Parent имеет значение null.

Ответ Кента положил меня на правильный путь, вот что я закончил:

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

Мне пришлось использовать PreviewKeyDown, потому что по умолчанию, когда вы нажимаете пробел в списке, он отменяет все, кроме последнего выбранного элемента.

4b9b3361

Ответ 1

Для начала разместите содержимое вне CheckBox:

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

После этого вам нужно будет убедиться, что нажатие пробела на ListBoxItem приводит к проверке CheckBox. Существует несколько способов сделать это, включая простой обработчик событий на ListBoxItem. Или вы можете указать обработчик для UIElement.KeyUp или что-то еще в DataTemplate:

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

Ответ 2

Вы также можете привязать свойство IsChecked свойств CheckBox и IsSelected ListBoxItem:

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

Ответ 3

В вашем примере использования было бы проще использовать ItemsControl вместо списка. Элемент ItemsControl аналогичен Listbox, за исключением того, что он не содержит автоматического выбора поведения. Это означает, что использование этого метода для размещения списка основных флажков очень простое, и вам не нужно обходить поведение выбора ListBox.

Простое переключение на ItemsControl даст вам именно то, что вам нужно:

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

Вы можете щелкнуть по тексту, чтобы отмечать флажки (поведение по умолчанию), и вы также можете использовать клавиатуру, не подключая никаких обработчиков событий.