更改源后 ICollectionView 排序不起作用

ICollectionView Sort doesn't work after changing source

我有一个使用 entity framework 查询数据库并将结果放在 ICollectionView 中的方法。 ICollectionView 充当 DataGridItemsSource。第一次查询一切正常,但第二次查询时,尽管应用了正确的 SortDescriptions.

,但数据排序不正确

这是我尝试查询和 grouping/sorting 数据的代码:

    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;
        }
    }

分组工作正常,但根据排序,分组的顺序不正确。我已经尝试了一些可能的 "fixes" 但没有成功(例如,将 sort/group 描述直接添加到 CollectionViewSource,在分组之前进行排序,删除一些 sorting/grouping,删除SortDescriptionsCollectionViewSource does not re-sort on property change).

有谁知道无论执行多少次查询,如何保持排序顺序?如果可行,我愿意接受在 DataGrid 中查询显示数据的其他方法。

尝试将您的 CollectionViewSource.Source 属性 绑定到您的 ObservableCollection<T> 属性。在视图模型构造函数中设置绑定。然后,别管它了。更新 ObservableCollection<T>,替换它,等等。只要它是一个 ObservableCollection<T> 并且它的 public 属性 每当你替换它时都会引发 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() 时,它在不参考组的情况下使用它们。不确定我明白它在那里做什么。