WPF的CollectionViewSource多个视图? [英] WPF CollectionViewSource Multiple Views?
问题描述
我已经使用搜索扩展名编写了一个自定义WPF控件,我们将其命名为 MyControl
。
Control是一个 ItemsControl
类的后代。
控制本身使用 过滤源集合的视图(因此将其显示在内部列表框中)。 您如何更改控件以避免此行为? 在这种情况下,您通常需要为集合的每个不同过滤使用情况创建一个单独的ICollectionView实例。使用ICollectionView的特定实现不是一个好主意,因为如果ItemsSource绑定到不同类型的集合,则可能需要更改CollectionView类型。使用 会给你一个ICollectionView,这个ICollectionView是自动正确的。 不幸的是,在这种情况下你可能会发现,将一个不同的集合应用到你的自定义控件的ItemsPresenter是非常困难的,因为所有的魔法都是由你的基础ItemsControl类完成的,并依赖于它管理的ItemsSource / Items属性。如果你实际上使用一个单独的ListBox控件(和TemplateBinding所有的ItemsSource属性,如果你需要它们的话),在你的内部使用类似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 filteredView = new CollectionViewSource {Source = newValue} .View;
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屋!