WPF的CollectionViewSource多个视图? [英] WPF CollectionViewSource Multiple Views?

查看:203
本文介绍了WPF的CollectionViewSource多个视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



控制本身使用

$ p $ protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue,System.Collections.IEnumerable newValue)
{
if(newValue!= null)
{
ICollectionView视图= CollectionViewSource。 GetDefaultView(NEWVALUE);
view.Filter + = this.FilterPredicate;


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

base.OnItemsSourceChanged(oldValue,newValue);





$ b

过滤源集合的视图(因此将其显示在内部列表框中)。
$ b 现在假设我们有10个在XAML中使用相同的DynamicSource定义的MyControls。
问题是,如果其中一个在源集合上应用Filter,它也会影响所有其他实例。



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

解决方案

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

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

会给你一个ICollectionView,这个ICollectionView是自动正确的。



不幸的是,在这种情况下你可能会发现,将一个不同的集合应用到你的自定义控件的ItemsPresenter是非常困难的,因为所有的魔法都是由你的基础ItemsControl类完成的,并依赖于它管理的ItemsSource / Items属性。如果你实际上使用一个单独的ListBox控件(和TemplateBinding所有的ItemsSource属性,如果你需要它们的话),在你的内部使用类似ItemsControl的默认模板的时候会发生这种情况。

ControlTemplate,那么你应该可以简单的在你的控件上添加一个新的ICollectionView DP(我建议只读)来保存你的集合的过滤版本,并将模板ListBox的ItemsSource绑定到这个新的属性上。


I've written a Custom WPF Control with search extension, let's name it MyControl. The Control is a descendent of an ItemsControl class.

So I feed the the data source to it like this:

The control itself uses

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);
}

to filter the view of the source collection (thus displaying it in an inner ListBox).

Now suppose we have 10 of these MyControls defined in XAML with the same DynamicSource. The problem is that if one of them applies the Filter on the source collection, it will affect all other instances too.

How would you change the Control to avoid this behaviour ?

解决方案

In situations like this you would generally want to create a separate ICollectionView instance for each differently filtered usage of the collection. It's not a good idea to use a specific implementation of ICollectionView since it's possible for the CollectionView type needed to change if the ItemsSource is bound to a different type of collection. Using

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

will give you an ICollectionView that's the correct type automatically.

Unfortunately, what you may find in this case is that it is very difficult to apply a different collection to the ItemsPresenter of your custom control since all of that magic is done for you by the base ItemsControl class and relies on the ItemsSource/Items properties which it manages. This happens when using something similar to ItemsControl's default template.

If you are in fact using a separate ListBox control (and TemplateBinding all the ItemsSource properties if you need them) inside your ControlTemplate then you should be able to simply add a new ICollectionView DP (I'd recommend read-only) on your control to hold your filtered version of the collection and bind the template ListBox's ItemsSource to that new property.

这篇关于WPF的CollectionViewSource多个视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆