如何在将项目绑定到ItemsSource时过滤集合?

时间:2013-04-18 06:59:16

标签: wpf mvvm count treeview

我创建了一个树形视图,用于模拟硬盘上的目录和文件。每个treeviewItem都有一个复选框,绑定到isSelected属性。我想要实现的是为每个父节点显示总文件数上所选文件的数量(选择12个总数的10/12个10个文件)。

有没有办法在属性所在的位置进行绑定??

<ContentPresenter Content="{Binding MyItems.Count where MyItems.IsSelected, Mode=OneTime}"
                  Margin="2,0" />

2 个答案:

答案 0 :(得分:14)

无法直接过滤绑定中的集合。但是,WPF允许使用CollectionViewSource过滤(和排序和分组)集合。

一种方法是在CollectionViewSource的资源中定义ItemTemplate,过滤ItemsSource并通过绑定到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>

在代码隐藏中:

private void FilteredItems_OnFilter(object sender, FilterEventArgs e)
{
    var item = sender as Item;
    e.Accepted = item.IsSelected;
}

我没有测试过,但它应该可以正常工作。你永远不会知道WPF,但是......

答案 1 :(得分:-13)

我个人使用以下框架 http://logofx.codeplex.com/ 这似乎符合您的所有要求(使用LogoFX.Mini,因为它似乎足以满足您的需要)。 使用WrappingCollection.WithSelection作为ItemsSource 使用SelectionCount作为要显示的值。 如果您决定不使用该框架,那么您应该通过专用行为订阅选择更改事件,创建专用依赖项属性并在每次选择更改时更新它。

最后一件事:绝对避免使用代码隐藏。它打破了整个MVVM原则。