ICollectionView排序在更改源后不起作用

时间:2016-10-31 14:09:44

标签: c# wpf entity-framework sorting icollectionview

我有一个使用实体框架查询数据库的方法,并将结果放在ICollectionView中。 ICollectionView充当ItemsSource的{​​{1}}。在第一次查询时一切正常,但在第二次查询时,尽管应用了正确的DataGrid,数据仍未正确排序。

以下是我尝试查询和分组/排序数据的代码:

SortDescriptions

分组工作正常,但是基于排序,组没有按正确的顺序排列。我已经尝试了许多可能的&#34;修复&#34;没有成功(例如,直接向 CollectionViewSource cvsRS; private ObservableCollection<productorder> rs; public ObservableCollection<productorder> RS { get { return rs; } set { if (rs != value) { rs = value; OnPropertyChanged("RS"); } } } private ICollectionView rsView; public ICollectionView RSView { get { return rsView; } set { if (rsView != value) { rsView = value; OnPropertyChanged("RSView"); } } } public void QueryDatabase() { RS = new ObservableCollection<productorder>(DatabaseEntities.productorders.Where(o => o.month.id == CurrentMonth.id)); if (RS != null) { cvsRS.Source = RS; RSView = cvsRS.View; RSView.GroupDescriptions.Clear(); RSView.GroupDescriptions.Add(new PropertyGroupDescription("producttype.productcategory.name")); RSView.GroupDescriptions.Add(new PropertyGroupDescription("producttype.name")); RSView.SortDescriptions.Clear(); RSView.SortDescriptions.Add(new SortDescription("producttype.productcategory.sortorder", ListSortDirection.Ascending)); RSView.SortDescriptions.Add(new SortDescription("client.name", ListSortDirection.Ascending)); RSView.Refresh(); CurrentRecord = null; SelectedRecords = null; } } 添加排序/组描述,在分组前排序,删除一些排序/分组,删除CollectionViewSourceCollectionViewSource does not re-sort on property change}。

有没有人知道如何维护排序顺序而不管执行了多少查询?如果可行的话,我可以选择在SortDescriptions中查询显示数据的替代方法。

1 个答案:

答案 0 :(得分:1)

尝试将CollectionViewSource.Source属性绑定到ObservableCollection<T>属性。在viewmodel构造函数中设置绑定。然后,不要管它。更新ObservableCollection<T>,替换它等等。只要它是ObservableCollection<T>且其公共属性在您更换它时会引发PropertyChanged,整个过程就会起作用。

public MyViewModel()
{
    BindCollectionViewSource();
}

protected void BindCollectionViewSource()
{
    cvsRS = new CollectionViewSource();

    var binding = new Binding
    {
        Source = this,
        Path = new PropertyPath("RS")
    };
    BindingOperations.SetBinding(cvsRS, CollectionViewSource.SourceProperty, binding);
}

//  Since we're not going to be messing with cvsRS or cvsRS.View after the 
//  constructor finishes, RSView can just be a plain getter. The value it returns 
//  will never change. 
public ICollectionView RSView
{
    get { return cvsRS.View; }
}

您不能只为Source分配绑定;除此之外还有更多。您在XAML中看到的Source="{Binding RSView}"内容可能看起来像是一项任务,但为方便起见,隐藏了一些细节。 Binding积极做事。它需要知道目标对象是谁。

我确实看到了一件有趣的事:我给了我的测试代码一个PropertyGroupDescription和一个SortDescription。当我将项目添加到集合中时,它会在组中对它们进行排序。然后,当我调用RSView.Refresh()时,它使用它们而不引用组。不确定我明白它在那里做了什么。