Windows runtime Metro App CollectionViewSource ObservableCollection筛选器
在WinRT中,似乎无法使用Windows runtime Metro App CollectionViewSource ObservableCollection筛选器,windows-runtime,microsoft-metro,winrt-xaml,observablecollection,collectionviewsource,Windows Runtime,Microsoft Metro,Winrt Xaml,Observablecollection,Collectionviewsource,在WinRT中,似乎无法使用CollectionViewSource过滤ObservableCollection: 我可以使用LINQ进行过滤,但是如果进行了影响过滤数据的更改,我如何让UI进行更新?您需要确保过滤更改是可见的,因此,您可以将CollectionViewSource的源设置为observateCollection,并对该集合进行更改,或者将CV的新源指定给新的过滤集合。我最终编写了自己的类以实现所需的效果: public class ObservableCollectionVi
CollectionViewSource
过滤ObservableCollection
:
我可以使用LINQ进行过滤,但是如果进行了影响过滤数据的更改,我如何让UI进行更新?您需要确保过滤更改是可见的,因此,您可以将
CollectionViewSource
的源设置为observateCollection
,并对该集合进行更改,或者将CV的新源指定给新的过滤集合。我最终编写了自己的类以实现所需的效果:
public class ObservableCollectionView<T> : ObservableCollection<T>
{
private ObservableCollection<T> _view;
private Predicate<T> _filter;
public ObservableCollectionView(IComparer<T> comparer)
: base(comparer)
{
}
public ObservableCollectionView(IComparer<T> comparer, IEnumerable<T> collection)
: base(comparer, collection)
{
}
public ObservableCollectionView(IComparer<T> comparer, IEnumerable<T> collection, Predicate<T> filter)
: base(comparer, collection == null ? new T[] { } : collection)
{
if (filter != null)
{
_filter = filter;
if (collection == null)
_view = new ObservableCollection<T>(comparer);
else
_view = new ObservableCollection<T>(comparer, collection);
}
}
public ObservableCollection<T> View
{
get
{
return (_filter == null ? this : _view);
}
}
public Predicate<T> Filter
{
get
{
return _filter;
}
set
{
if (value == null)
{
_filter = null;
_view = new ObservableCollection<T>(Comparer);
}
else
{
_filter = value;
Fill();
}
}
}
private void Fill()
{
_view = new ObservableCollection<T>(Comparer);
foreach (T item in this)
{
if (Filter(item))
View.Add(item);
}
}
private int this[T item]
{
get
{
int foundIndex = -1;
for (int index = 0; index < View.Count; index++)
{
if (View[index].Equals(item))
{
foundIndex = index;
break;
}
}
return foundIndex;
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
if (_filter != null)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (T item in e.NewItems)
if (Filter(item))
View.Add(item);
break;
case NotifyCollectionChangedAction.Move:
break;
case NotifyCollectionChangedAction.Remove:
foreach (T item in e.OldItems)
if (Filter(item))
View.Remove(item);
break;
case NotifyCollectionChangedAction.Replace:
for (int index = 0; index < e.OldItems.Count; index++)
{
T item = (T)e.OldItems[index];
if (Filter(item))
{
int foundIndex = this[item];
if (foundIndex != -1)
View[foundIndex] = (T)e.NewItems[index];
}
}
break;
case NotifyCollectionChangedAction.Reset:
Fill();
break;
}
}
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (_filter != null)
{
// TODO: Implement code for property changes
}
}
}
公共类ObservableCollection视图:ObservableCollection
{
私有可观察收集视图;
私有谓词过滤器;
公共可见集合视图(IComparer比较器)
:基准(比较器)
{
}
公共ObservableCollectionView(IComparer比较器、IEnumerable集合)
:base(比较器、集合)
{
}
公共ObservableCollectionView(IComparer比较器、IEnumerable集合、谓词筛选器)
:base(比较器,集合==null?新的T[]{}:collection)
{
if(过滤器!=null)
{
_过滤器=过滤器;
if(集合==null)
_视图=新的可观察集合(比较器);
其他的
_视图=新的可观察集合(比较器、集合);
}
}
公共可观测集合视图
{
得到
{
返回(_filter==null?此:_视图);
}
}
公共谓词过滤器
{
得到
{
返回过滤器;
}
设置
{
如果(值==null)
{
_filter=null;
_视图=新的可观察集合(比较器);
}
其他的
{
_过滤器=值;
填充();
}
}
}
私人空间填充()
{
_视图=新的可观察集合(比较器);
foreach(本文件中的T项)
{
if(过滤器(项目))
查看。添加(项目);
}
}
私人int本[T项]
{
得到
{
int foundIndex=-1;
for(int index=0;index
还不完美。因此,欢迎改进/建议
现在可以使用View属性将此对象直接绑定到控件。我有一个源ObservableCollection,我过滤它并返回IEnumerable。然后我将其传递给ObservableCollection的构造函数并分配给CollectionViewSource。对源ObservableCollection进行更新。现在,源集合和已筛选集合之间的连接断开,因此对源集合所做的更改不会被筛选器拾取。如何克服此问题?您需要再次筛选并分配它。或者在更新原始集合时更新筛选的集合。我有。。。见下面我的答案。不完美。。。然而你能举一个简单的用法例子吗?最好理解这个类的目的/优点。目的:一个可排序和过滤的ObservableCollection。创建此对象的实例,像通常使用ObservableCollection一样使用。具有谓词形式的筛选器属性,因此可以筛选数据。然后在绑定到控件时,绑定到View属性。就这样!很好的解决方案。我将在我的项目中使用这个暂时!我不理解是否存在使用IComparer
参数的构造函数重载。这些重载不存在于ObservableCollection
中,因此a)在该视图实现中似乎不需要它们,b)上述内容不会编译,因为base
调用无效(重载不存在于基类中)。