【问题标题】:Filtering CollectionViewSource with multiple filters使用多个过滤器过滤 CollectionViewSource
【发布时间】:2020-03-04 16:35:26
【问题描述】:

我正在阅读此内容:https://social.technet.microsoft.com/wiki/contents/articles/26673.wpf-collectionview-tips.aspx 并尝试将其应用于我的代码但没有成功。

PendingTrucks = (CollectionView)new CollectionViewSource { Source = TruckLog }.View;
ParkedTrucks = (CollectionView)new CollectionViewSource { Source = TruckLog }.View;


PendingTrucks.Filter += PendingTrucks_Filter;
ParkedTrucks.Filter += PendingTrucks_Filter;

public static ICollectionView PendingTrucks
        {
            get; set;
        }

        public static ICollectionView ParkedTrucks
        {
            get; set;
        }



static bool PendingTrucks_Filter (object value)
{
            if (value is Truck truck)
            {
                return truck.ParkItem is null;
            }

            // Fallbackvalue 
            return true;
        }

        static bool ParkedTrucks_Filter (object value)
        {
            if (value is Truck truck)
            {
                return truck.status == 2;
            }

            // Fallbackvalue 
            return true;
        }


我收到以下错误:NullReferenceException: Object reference not set to an instance of an object.

当它尝试加载带有绑定到视图的数据网格的表单时显示错误。

这是我得到的调用堆栈:

This exception was originally thrown at this call stack:
    System.Windows.Data.ListCollectionView.CanAddNew.get()
    System.Windows.Controls.ItemCollection.System.ComponentModel.IEditableCollectionView.CanAddNew.get()
    System.Windows.Controls.DataGrid.OnCoerceCanUserAddOrDeleteRows(System.Windows.Controls.DataGrid, bool, bool)
    System.Windows.Controls.DataGrid.OnCoerceCanUserAddRows(System.Windows.DependencyObject, object)
    System.Windows.DependencyObject.ProcessCoerceValue(System.Windows.DependencyProperty, System.Windows.PropertyMetadata, ref System.Windows.EntryIndex, ref int, ref System.Windows.EffectiveValueEntry, ref System.Windows.EffectiveValueEntry, ref object, object, object, System.Windows.CoerceValueCallback, bool, bool, bool)
    System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex, System.Windows.DependencyProperty, System.Windows.PropertyMetadata, System.Windows.EffectiveValueEntry, ref System.Windows.EffectiveValueEntry, bool, bool, System.Windows.OperationType)
    System.Windows.DependencyObject.CoerceValue(System.Windows.DependencyProperty)
    System.Windows.Controls.DataGrid.OnItemsSourceChanged(System.Collections.IEnumerable, System.Collections.IEnumerable)
    System.Windows.Controls.ItemsControl.OnItemsSourceChanged(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
    System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
    ...
    [Call Stack Truncated]

【问题讨论】:

    标签: wpf collectionviewsource icollectionview


    【解决方案1】:

    试试这个:

    这是ICollectionView 的源集合。您从集合中添加/删除项目,ICollectionView 会自动更新。

    private ObservableCollection<Truck> Trucks { get; }
    

    绑定到 DataGrid 的集合视图:

    public ICollectionView PendingTrucksCollectionView { get; }
    public ICollectionView ParkedTrucksCollectionView { get; }
    

    在 ViewModel 构造函数上初始化源集合和视图。在这里你可以传递一个对象来填充 observable 集合,或者一个 IEnumerable 来填充卡车集合。

    public ViewModel() : this(Enumerable.Empty<Truck>())
    { }
    
    
    public ViewModel(IEnumerable<Truck> trucks)
    {
        // Collection Source
        Trucks = new ObservableCollection<Truck>(trucks);
    
        // Collection Views
        PendingTrucksCollectionView = CollectionViewSource.GetDefaultView(Trucks);
        ParkedTrucksCollectionView = CollectionViewSource.GetDefaultView(Trucks);
    
        // Collection View Filters
        PendingTrucksCollectionView.Filter = PendingTrucksFilter;
        ParkedTrucksCollectionView.Filter = ParkedTrucksFilter;
    }
    
    private bool PendingTrucksFilter(object value)
    {
        return value is Truck truck && truck.ParkItem is null;
    }
    
    private bool ParkedTrucksFilter(object value)
    {
        return value is Truck truck && truck.status == 2;
    }
    


    希望这会有所帮助。

    【讨论】:

    • 这似乎可行。我只是放弃了整个过滤器并使用了一种方法,然后在 collectionchanged 上触发了过滤器方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    相关资源
    最近更新 更多