使用ICollectionView过滤ObservableCollection
我有一个绑定到dataGrid
ObservableCollection
现在我想过滤所呈现的数据我看到我需要使用ICollectionView
但我不知道如何使用我的MVVM
模式添加ICollectionView
。
我简化的代码如下:
public class MainViewModel : ViewModelBase , IBarcodeHandler { public ObservableCollection TraceItemCollectionViewSource { get; set; } }
我的XAML
<Window xmlns:controls="clr-namespace:Mentor.Valor.vManage.RepairStation.Controls" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
我如何在这里添加ICollectionView
以便对视图应用过滤?
你需要:
public class MainViewModel : ViewModelBase, IBarcodeHandler { public ICollectionView TraceItemCollectionView { get { return CollectionViewSource.GetDefaultView(TraceItemCollectionViewSource); } } public ObservableCollection TraceItemCollectionViewSource { get; set; } }
然后,代码中的某个地方(可能在构造函数中)添加您的filter:
TraceItemCollectionView.Filter = o => { var item = (TraceDataItem) o; //based on item, return true if it should be visible, or false if not return true; };
而且,在XAML中,您需要更改与TraceItemCollectionView属性的绑定。
CollectionView
并不总是最佳解决方案。 您还可以使用一些简单的LinQ过滤您的collections。 举个简单的例子:
public ObservableCollection FilteredData { get { return new ObservableCollection (YourUnfilteredCollection.Where( i => MeetsFilterRequirements(i))); } } private bool MeetsFilterRequirements(TraceDataItem item) { return item.SomeProperty == someValue || item is SomeType; }
这种方法的优点是可以添加一些复杂的过滤要求。 需要注意的一点是:每当更改此方法中的任何属性时,您都需要调用NotifyPropertyChanged("FilteredData")
以确保相应地更新UI。
您可以从Command调用Filter回调并从CollectionViewSource公开View属性:
public class ViewModel: INotifyPropertyChanged { private CollectionViewSource data = new CollectionViewSource(); private ObservableCollection observableChilds = new ObservableCollection (); public ViewModel() { var model = new Model(); model.ChildList.Add(new Child { Name = "Child 1" }); model.ChildList.Add(new Child { Name = "Child 2" }); model.ChildList.Add(new Child { Name = "Child 3" }); model.ChildList.Add(new Child { Name = "Child 4" }); //Populate ObservableCollection model.ChildList.ToList().ForEach(child => observableChilds.Add(child)); this.data.Source = observableChilds; ApplyFilterCommand = new DelegateCommand(OnApplyFilterCommand); } public ICollectionView ChildCollection { get { return data.View; } } public DelegateCommand ApplyFilterCommand { get; set; } private void OnApplyFilterCommand() { data.View.Filter = new Predicate