WPF CollectionViewSource多个视图?

时间:2010-01-29 07:19:37

标签: wpf filter controls collectionviewsource

我编写了一个带有搜索扩展名的自定义WPF控件,我们将其命名为MyControl。 控件是ItemsControl类的后代。

所以我像这样将数据源提供给它:

控件本身使用

protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
{
    if (newValue != null)
    {
        ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
        view.Filter += this.FilterPredicate;
    }

    if (oldValue != null)
    {
        ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
        view.Filter -= this.FilterPredicate;
    }

    base.OnItemsSourceChanged(oldValue, newValue);
}

过滤源集合的视图(从而在内部ListBox中显示它)。

现在假设我们在XAML中定义了10个具有相同DynamicSource的MyControl。 问题是如果其中一个在源集合上应用Filter,它也会影响所有其他实例。

如何更改控件以避免此行为?

2 个答案:

答案 0 :(得分:35)

在这种情况下,您通常希望为集合的每个不同过滤使用创建单独的ICollectionView实例。使用ICollectionView的特定实现并不是一个好主意,因为如果ItemsSource绑定到不同类型的集合,则可能需要更改CollectionView类型。使用

 ICollectionView filteredView = new CollectionViewSource { Source=newValue }.View;

将自动为您提供正确类型的ICollectionView。

不幸的是,在这种情况下您可能会发现很难将不同的集合应用于自定义控件的ItemsPresenter,因为基本的ItemsControl类为您完成了所有这些魔法并且依赖于ItemsSource /它管理的项目属性。当使用与ItemsControl的默认模板类似的东西时会发生这种情况。

如果您实际上在ControlTemplate中使用单独的ListBox控件(并且如果需要,还有TemplateBinding所有ItemsSource属性),那么您应该能够简单地添加一个新的ICollectionView DP(我建议只读)您可以控制集合的过滤版本并将模板ListBox的ItemsSource绑定到该新属性。

答案 1 :(得分:5)

问题是CollectionViewSource.GetDefaultView(object)将始终为给定的源返回相同的ICollectionView实例,这就是显示该源时所有ItemsControl扩展名将使用的内容。

您可以通过创建一个新的ICollectionView实例来解决这个问题,该实例将由您希望能够独立过滤集合的每个控件使用,然后显式绑定每个ItemsSource属性。控制到该特定视图。所需的ICollectionView类型取决于您的方案,但ListCollectionView通常是合适的。