使用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(x => ((Child)x).Name == "Child 1"); OnPropertyChanged("ChildCollection"); } } //Sample Model used public class Model { public Model() { ChildList = new HashSet(); } public ICollection ChildList { get; set; } } public class Child { public string Name { get; set; } } //View