使用ICollectionView过滤ObservableCollection

时间:2015-06-18 13:18:08

标签: c# wpf xaml mvvm data-binding

我已将ObservableCollection绑定到dataGrid,现在我想过滤显示的数据,我看到我需要使用ICollectionView,但我不确定如何添加{{1}使用我的ICollectionView模式。

我简化的代码如下:

MVVM

我的XAML

public class MainViewModel : ViewModelBase , IBarcodeHandler
{
    public ObservableCollection<TraceDataItem> TraceItemCollectionViewSource { get; set; }
}

如何在此处添加 <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" <DataGrid Grid.Row="2" ColumnWidth="*" ItemsSource="{Binding TraceItemCollectionViewSource , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" RowStyle="{StaticResource TraceRowStyle}" IsReadOnly="True" Name="TraceDataGrid" Margin="5,5,5,5" Padding="5,5,5,5" AutoGenerateColumns="False"> </Window> 以便对视图应用过滤?

3 个答案:

答案 0 :(得分:5)

你需要:

public class MainViewModel : ViewModelBase, IBarcodeHandler
{
    public ICollectionView TraceItemCollectionView
    {
        get { return CollectionViewSource.GetDefaultView(TraceItemCollectionViewSource); }
    }

    public ObservableCollection<TraceDataItem> TraceItemCollectionViewSource { get; set; }
}

然后,代码中的某个地方(可能在构造函数中)添加过滤器:

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属性。

答案 1 :(得分:0)

public ObservableCollection<TraceDataItem> FilteredData { get { return new ObservableCollection<TraceDataItem>(YourUnfilteredCollection.Where( i => MeetsFilterRequirements(i))); } } private bool MeetsFilterRequirements(TraceDataItem item) { return item.SomeProperty == someValue || item is SomeType; } 并不总是最佳解决方案。您还可以使用一些简单的LinQ过滤您的收藏。举个简单的例子:

NotifyPropertyChanged("FilteredData")

这种方法的优点在于您可以添加一些复杂的过滤要求。需要注意的一点是:无论何时更改此方法中的任何属性,您都需要调用Image以确保相应地更新UI。

答案 2 :(得分:0)

您可以从Command调用Filter回调并从CollectionViewSource公开View属性:

public class ViewModel: INotifyPropertyChanged
{
    private CollectionViewSource data = new CollectionViewSource();
    private ObservableCollection<Child> observableChilds = new ObservableCollection<Child>();

    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<object>(x => ((Child)x).Name == "Child 1");
        OnPropertyChanged("ChildCollection");
    }
}

//Sample Model used
public class Model
{
    public Model() 
    {
        ChildList = new HashSet<Child>();
    }

    public ICollection<Child> ChildList { get; set; }
}

public class Child
{
    public string Name { get; set; }
}

//View
<ListBox ItemsSource="{Binding Path = ChildCollection}" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<Button Command="{Binding ApplyFilterCommand}"/>