wpf 将复选框列表绑定到选中值列表的最简单方法是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/782980/
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
What's the simplest way to bind a list of checkboxes to a list of checked values
提问by Anthony Brien
I have a list of AvailableItems
that I want to display as a list of checkboxes, so that users can pick which items to generate, which are then stored in another list called ItemsToGenerate
(my lists are actually just lists of strings).
我有一个AvailableItems
我想显示为复选框列表的列表,以便用户可以选择要生成的项目,然后将其存储在另一个名为的ItemsToGenerate
列表中(我的列表实际上只是字符串列表)。
Showing all available items with corresponding checkboxes is easy:
显示带有相应复选框的所有可用项目很容易:
<ItemsControl ItemsSource="{Binding Path=AvailableItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But now I need to bind each Checkbox.IsChecked property, to the fact that the item is in the ItemsToGenerate
list. I thought of making a ListContainmentToBoolConverter
like this:
但是现在我需要将每个 Checkbox.IsChecked 属性绑定到该项目在ItemsToGenerate
列表中的事实。我想制作一个ListContainmentToBoolConverter
这样的:
IsChecked="{Binding Path=ItemsToGenerate,
Converter={StaticResource ListContainmentToBoolConverter}}"
But that doesn't work because I'm missing a ConverterParameter
to pass the value of each item, but I can't do that, because ConverterParameter
does not support binding.
但这不起作用,因为我缺少ConverterParameter
传递每个项目的值的一个,但我不能这样做,因为ConverterParameter
不支持绑定。
Any ideas?
有任何想法吗?
回答by Anthony Brien
I've found a solution to my problem.
我找到了解决我的问题的方法。
I've changed my ItemsControl
to a ListBox
, and added a binding between the SelectedItems with my ItemsToGenerate
collection using the technique described here. It basically allows me to synchronize any custom collection to ListBox.SelectedItems
using a simple attached property.
我已将 my 更改ItemsControl
为 a ListBox
,并ItemsToGenerate
使用此处描述的技术在 SelectedItems 与我的集合之间添加了一个绑定。它基本上允许我ListBox.SelectedItems
使用简单的附加属性来同步任何自定义集合。
<ListBox ItemsSource="{Binding AvailableItems}"
Behaviors:MultiSelectorBehaviours.SynchronizedSelectedItems=
"{Binding ItemsToGenerate}"
SelectionMode="Multiple"
Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}"
Margin="3"
IsChecked="{Binding RelativeSource=
{RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},
Path=IsSelected}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
I'm still able to display this as I initially wanted (a list of checkboxes), by adding a data template to change each ListBoxItem
to a checkbox and binding each Checkbox.IsChecked
to ListBoxItem.IsSelected
.
通过添加数据模板以将每个更改ListBoxItem
为一个复选框并将每个绑定Checkbox.IsChecked
到ListBoxItem.IsSelected
.
I had this pattern in so many places in my application that this is the ideal solution for me, because now I just need to specify one attached property, and the rest is all handled by the data bindings, and I don't need any additional code.
我在应用程序的很多地方都有这种模式,这对我来说是理想的解决方案,因为现在我只需要指定一个附加属性,其余的都由数据绑定处理,我不需要任何额外的代码。
回答by Denis Troller
I honestly would create a list of objects containing both the string and a boolean indicating if it is checked.
老实说,我会创建一个包含字符串和布尔值的对象列表,指示它是否被选中。
With a little Linq you can generate your list of objects and bind it to itemSource instead of binding the list of strings.
使用一点 Linq,您可以生成对象列表并将其绑定到 itemSource 而不是绑定字符串列表。
It will be simpler in the end, especially if you actually need to update something if the user is allowed to check/uncheck the checkboxes.
最后它会更简单,特别是如果允许用户选中/取消选中复选框,您实际上需要更新某些内容。
== update ==
== 更新 ==
in answer to the comment, my take on this because I'm not sure I understand what the actual problem would be: provided we have the full list (AvailableItems) and the list of selected items (ItemsToGenerate):
在回答评论时,我对此的看法是因为我不确定我理解实际问题是什么:前提是我们有完整列表 (AvailableItems) 和选定项目列表 (ItemsToGenerate):
public class ItemEntry
{
public string Name { get; set; }
public bool IsSelected {get; set; }
}
...
...
_Items = from item in AvailableItems
select new ItemEntry() {
Name = item,
IsSelected = ItemsToGenerate.contains(item)
}).ToList();
You can then bind your list like so, by exposing _Items as a property named Items:
然后,您可以像这样绑定您的列表,方法是将 _Items 公开为名为 Items 的属性:
<ItemsControl ItemsSource="{Binding Path=Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can at a later time select from _Items where IsSelected is true to get the selected items if you need to.
如果需要,您可以稍后从 _Items 中选择,其中 IsSelected 为 true 以获取所选项目。
Also, if ItemsToGenerate can get big, you should create a HashSet of the values and use it in the query, that should make it faster if need be.
此外,如果 ItemsToGenerate 可以变大,您应该创建一个值的 HashSet 并在查询中使用它,如果需要,这应该使它更快。