Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
652 views
in Technique[技术] by (71.8m points)

filter - WPF CollectionViewSource Multiple Views?

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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...