ICollectionView不支持对其sourcecollection的更改

时间:2017-03-09 16:43:46

标签: .net wpf

我正在使用WPF应用程序,并且我最近在ICollectionView中包含了几个ObservableCollections,以便我可以实现排序和过滤。

Private _EntriesSource As New BankEntry.Collection
Public ReadOnly Property Entries As ICollectionView = Windows.Data.CollectionViewSource.GetDefaultView(_EntriesSource)

排序和过滤效果很好,但是由于这样做似乎不那么线程友好,尽管在Dispatcher线程调用或使用BindingOperations.EnableCollectionSynchronization包装任何触及集合的东西我仍然会收到错误,说这个集合不支持改变其源集合......

我尝试做的事情的例子只是MyCollection.Add(item)或MyCollection.Remove(item)。

从ObservableCollections转移到ICollectionView,我是否走错了方向? 有没有更好的方法来排序和过滤ObservableCollections,同时保持从集合中添加和删除项目的能力?

1 个答案:

答案 0 :(得分:0)

在大多数情况下,排序和分组数据是View(不是CollectionView而是MVVM视图)的函数,因此最好的方法是在XAML中创建CollectionViewSource绑定到可观察集合,然后绑定你的对CollectionViewSource的控件

<StackPanel>
    <StackPanel.Resources>
        <CollectionViewSource x:Key="cvsBodies" Source="{Binding Bodies}" Filter="CollectionViewSource_Filter">
            <CollectionViewSource.SortDescriptions>
                <ComponentModel:SortDescription Direction="Ascending" PropertyName="Name"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </StackPanel.Resources>
    <ItemsControl ItemsSource="{Binding Mode=OneWay, Source={StaticResource cvsBodies}}"/>
</StackPanel>

您还可以在VM上创建CollectionViewSource

public class VM
{
    public VM()
    {
        CollectionView.Source = Items;
        CollectionView.Filter += CollectionView_Filter;
        //only required if you are initialising the collection with values
        CollectionView.View.Refresh();

    }

    private void CollectionView_Filter(object sender, FilterEventArgs e)
    {
         //filter logic
    }

    public CollectionViewSource CollectionView { get; } = new CollectionViewSource();
    public ObservableCollection<int> Items { get; } = new ObservableCollection<int>(Enumerable.Range(1,1000) );
}