wpf 将集合绑定到 ItemsSource 时如何过滤集合?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16076453/
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
How to filter a collection when binding it to ItemsSource?
提问by G. Abitbol
I created a treeview which modelizes directories and files on my hard drive. Each treeviewItem has a checkbox, binded to a isSelected property. What I'd like to achieve is display for each parent node the count of selected files on the total files count (10 / 12 10 files on twelve total selected).
我创建了一个树视图,它对硬盘驱动器上的目录和文件进行建模。每个 treeviewItem 都有一个复选框,绑定到 isSelected 属性。我想要实现的是为每个父节点显示总文件数中所选文件的数量(10 / 12 10 个文件,总共选择了 12 个)。
Is there a way to do a binding with where property is ...?
有没有办法绑定 where 属性是 ...?
<ContentPresenter Content="{Binding MyItems.Count where MyItems.IsSelected, Mode=OneTime}"
Margin="2,0" />
回答by Marc
There is no way to directly filter the collection in the binding. However, WPF allows filtering (and sorting and grouping) collections with CollectionViewSource.
没有办法直接过滤绑定中的集合。但是,WPF 允许使用CollectionViewSource.
One approach would be to define a CollectionViewSourcein the resources of your ItemTemplatewhich filters the ItemsSourcean get the number of elements which pass the filter by binding to the Count property of this CollectionViewSource. You have to define your filter in codebehind, though. Would look something like this:
一种方法是CollectionViewSource在您的ItemTemplatewhich 过滤器的资源中定义 a并ItemsSource通过绑定到 this 的 Count 属性来获取通过过滤器的元素数量CollectionViewSource。不过,您必须在代码隐藏中定义过滤器。看起来像这样:
<TreeView x:Name="Tree" ItemsSource="{Binding Items}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ChildItems}">
<HierarchicalDataTemplate.Resources>
<CollectionViewSource x:Key="FilteredItems"
Source="{Binding ChildItems}"
Filter="FilteredItems_OnFilter" />
</HierarchicalDataTemplate.Resources>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{} {0} of {1} selected">
<Binding Path="Count" Source="{StaticResource FilteredItems}" />
<Binding Path="ItemsSource.Count" ElementName="Tree" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
And in the codebehind:
在代码隐藏中:
private void FilteredItems_OnFilter(object sender, FilterEventArgs e)
{
var item = sender as Item;
e.Accepted = item.IsSelected;
}
I haven't tested it but it should work in general. You never know with WPF, though...
我还没有测试过,但它应该可以正常工作。但是,您永远不会知道 WPF...
回答by Gena Verdel
I personally use the following framework http://logofx.codeplex.com/which seems to meet all your requirements (use LogoFX.Mini as it seems enough for your purposes). Use WrappingCollection.WithSelection as your ItemsSource Use SelectionCount as the value you want to display. If you decide not to use the framework, then you should subscribe for selection changed event via dedicated behavior, create dedicated dependency property and update it each time the selection changes.
我个人使用以下框架 http://logofx.codeplex.com/它似乎满足您的所有要求(使用 LogoFX.Mini 似乎足以满足您的目的)。使用 WrappingCollection.WithSelection 作为您的 ItemsSource 使用 SelectionCount 作为您想要显示的值。如果您决定不使用该框架,那么您应该通过专用行为订阅选择更改事件,创建专用依赖属性并在每次选择更改时更新它。
And one last thing: Definitely avoid using code-behind. It breaks the whole MVVM principle.
最后一件事:绝对避免使用代码隐藏。它打破了整个 MVVM 原则。

