WPF ListBoxItem 选择问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/127556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF ListBoxItem selection problem
提问by 17 of 26
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.
我遇到的问题是,当我单击复选框或其内容时,没有选择父 ListBoxItem。如果我单击复选框旁边的空白区域,ListBoxItem 会被选中。
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.
在上面的代码中,当我单击复选框时,e.Handled 为 false,chkBox.Parent 为 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.
我必须使用 PreviewKeyDown,因为默认情况下,当您点击列表框中的空格键时,它会取消选择除最近选择的项目之外的所有内容。
采纳答案by Kent Boogaart
To begin with, put the content outside the CheckBox
:
首先,将内容放在 之外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
:
之后,您需要确保在 a 上按下空格会ListBoxItem
导致CheckBox
被检查。有多种方法可以做到这一点,包括在ListBoxItem
. 或者您可以UIElement.KeyUp
在您的DataTemplate
.
<CheckBox IsChecked="{Binding IsChecked}" UIElement.KeyUp="..."/>
回答by Vassili Altynikov
You can also bind the IsChecked property of the CheckBox and IsSelected property of the ListBoxItem:
您还可以绑定 CheckBox 的 IsChecked 属性和 ListBoxItem 的 IsSelected 属性:
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding DisplayText}" IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
回答by Patrick Klug
In your use case it would be way simpler to use a ItemsControl
instead of a list box. A ItemsControl is similar to a Listbox except that it doesn't contain the automatic selection behaviour. Which means that using it to host a list of what are essentially checkboxes is very simple and you don't have to workaround the ListBox's selection behaviour.
在您的用例中,使用 aItemsControl
而不是列表框会更简单。ItemsControl 类似于 Listbox,只是它不包含自动选择行为。这意味着使用它来托管本质上是复选框的列表非常简单,您不必解决 ListBox 的选择行为。
Simply switching to ItemsControl will give you exactly what you need:
只需切换到 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>
You can click on text to check checkboxes (default behavior) and you can use the keyboard too without having to wire up any event handlers.
您可以单击文本以选中复选框(默认行为),您也可以使用键盘而无需连接任何事件处理程序。