Metro App CollectionViewSource ObservableCollection筛选器 [英] Metro App CollectionViewSource ObservableCollection Filter
本文介绍了Metro App CollectionViewSource ObservableCollection筛选器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在 WinRT 中似乎无法使用CollectionViewSource
过滤ObservableCollection
:
It appears that filtering an ObservableCollection
with CollectionViewSource
is not possible in WinRT:
我可以使用 LINQ 进行过滤,但是如果进行了影响已过滤数据的更改,如何获取 UI 来进行更新?
I can filter using LINQ, but how do I get the UI to update if changes that affect the filtered data are made?
推荐答案
我最终编写了自己的类,以实现所需的效果:
I ended up writing my own class to achieve the desired effect:
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
}
}
}
尚不完美.因此欢迎您提出改进/建议.
Not yet perfect. So improvements/suggestions welcomed.
您现在可以使用View属性将该对象直接绑定到控件.
You can now bind this object, directly to a control using the View property.
这篇关于Metro App CollectionViewSource ObservableCollection筛选器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文