WPF CollectionViewSource多个视图?

PaN*_*1Me 17 wpf controls filter 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Joh*_*wen 38

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

 ICollectionView filteredView = new CollectionViewSource { Source=newValue }.View;
Run Code Online (Sandbox Code Playgroud)

会自动给你一个ICollectionView,它是正确的类型.

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

如果您实际上在ControlTemplate中使用单独的ListBox控件(以及TemplateBinding所有ItemsSource属性,如果您需要它们),那么您应该只需在控件上添加一个新的ICollectionView DP(我建议您使用只读)保存集合的过滤版本,并将模板ListBox的ItemsSource绑定到该新属性.

  • 是.它不仅仅是更改初始化:private static readonly DependencyPropertyKey MyDPPropertyKey = DependencyProperty.RegisterReadOnly(...); public static readonly DependencyProperty MyDPProperty = MyDPPropertyKey.DependencyProperty; public object MyDP {get {return(object)GetValue(MyDPProperty); } private set {SetValue(MyDPPropertyKey,value); }} (2认同)

Ste*_*rex 5

存在的问题CollectionViewSource.GetDefaultView(object)总是返回ICollectionView给定源的相同实例,这是任何ItemsControl扩展在显示该源时将使用的.

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