Проблема выбора WPF ListBoxItem - PullRequest
       11

Проблема выбора WPF ListBoxItem

19 голосов
/ 24 сентября 2008

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

<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, потому что по умолчанию, когда вы нажимаете пробел в списке, он отменяет выбор всего, кроме самого последнего выбранного элемента.

Ответы [ 3 ]

10 голосов
/ 24 сентября 2008

Для начала поместите содержимое за пределы 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="..."/>
3 голосов
/ 25 сентября 2008

Вы также можете привязать свойство 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>
2 голосов
/ 19 октября 2011

В вашем случае было бы проще использовать 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>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...