仅供参考,另一种方法是使用CollectionViewSource 上的附加属性,然后将函数通过管道传输到ViewModel(实现接口)。
这是一个非常基本的演示,仅用于过滤,它需要一些工作,例如VM 上的第二个集合,但我认为它足以展示一般技术。
如果这比其他方法更好或更差有待讨论,我只想指出,还有另一种方法可以做到这一点
附加属性的定义:
public static class CollectionViewSourceFilter
{
public static IFilterCollectionViewSource GetFilterObject(CollectionViewSource obj)
{
return (IFilterCollectionViewSource)obj.GetValue(FilterObjectProperty);
}
public static void SetFilterObject(CollectionViewSource obj, IFilterCollectionViewSource value)
{
obj.SetValue(FilterObjectProperty, value);
}
public static void FilterObjectChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.OldValue is IFilterCollectionViewSource oldFilterObject
&& sender is CollectionViewSource oldCvs)
{
oldCvs.Filter -= oldFilterObject.Filter;
oldFilterObject.FilterRefresh -= (s, e2) => oldCvs.View.Refresh();
}
if (e.NewValue is IFilterCollectionViewSource filterObject
&& sender is CollectionViewSource cvs)
{
cvs.Filter += filterObject.Filter;
filterObject.FilterRefresh += (s,e2) => cvs.View.Refresh();
}
}
public static readonly DependencyProperty FilterObjectProperty = DependencyProperty.RegisterAttached(
"FilterObject",
typeof(Interfaces.IFilterCollectionViewSource),
typeof(CollectionViewSourceFilter),
new PropertyMetadata(null,FilterObjectChanged)
);
}
界面:
public interface IFilterCollectionViewSource
{
void Filter(object sender, FilterEventArgs e);
event EventHandler FilterRefresh;
}
xaml 中的用法:
<CollectionViewSource
x:Key="yourKey"
Source="{Binding YourCollection}"
classes:CollectionViewSourceFilter.FilterObject="{Binding}" />
以及在 ViewModel 中的使用:
class YourViewModel : IFilterCollectionViewSource
{
public event EventHandler FilterRefresh;
private string _SearchTerm = string.Empty;
public string SearchTerm
{
get { return _SearchTerm; }
set {
SetProperty(ref _SearchTerm, value);
FilterRefresh?.Invoke(this, null);
}
}
private ObservableCollection<YourItemType> _YourCollection = new ObservableCollection<YourItemType>();
public ObservableCollection<YourItemType> YourCollection
{
get { return _YourCollection; }
set { SetProperty(ref _YourCollection, value); }
}
public void Filter(object sender, FilterEventArgs e)
{
e.Accepted = (e.Item as YourItemType)?.YourProperty?.ToLower().Contains(SearchTerm.ToLower()) ?? true;
}
}