如何扩展CollectionView的过滤器?

时间:2019-01-10 00:00:00

标签: c# wpf binding

我有一个代表集合的类,并实现以下接口:

  • IEnumerable,以便我可以将WPF ItemsControl.ItemsSource绑定到它。
  • ICollectionViewFactory使用我可以配置的视图,而不是创建默认视图

到目前为止,一切都很好:我可以绑定控件,包括排序,过滤甚至“实时整形”。

第一个问题:由于ICollectionViewFactoryIEnumerable.GetEnumerator从未被用户界面调用过,但仍然是必需的。 我应该在这里闻些什么吗?

然后,在一个特定的场景中,我想进行一些其他过滤,并且条件将取决于渲染上下文,这就是为什么我认为我将IValueConverter与以下内容一起使用的原因:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    var cv = (ICollectionViewFactory)value.CreateView();
    cv.ExtendFilter(i => i.AdditionalFilterProperty);

    return cv;
}

ExtendFilter扩展方法如下:

public static void ExtendFilter(this ICollectionView view, Predicate<object> filter)
{
    if (view.Filter == null)
    {
        view.Filter = filter;
    }
    else
    {
        var originalFilter = view.Filter;
        view.Filter = item => originalFilter(item) && filter(item);
    }
}

第二个问题:有更好的方法吗?我在想,也许是表情树...

1 个答案:

答案 0 :(得分:1)

首先,如果您的集合类实现了IEnumerable,则不会调用ICollectionViewFactory是正确的。 在WPF框架的深处,ItemsSourceIEnumerable)已创建其默认集合视图。在该代码中,如果集合已实现ICollectionViewFactory,则它将CreateView作为实际项源。如果未实现,则它将创建一个默认视图,并以IEnumerable作为项目来源。

第二,您的复合过滤器逻辑似乎很合理。表达式树需要更多的实现,但是也将提供一个好的解决方案。我个人会坚持你拥有的东西