【问题标题】:ICollectionView Sort doesn't work after changing source更改源后,ICollectionView 排序不起作用
【发布时间】:2016-10-31 14:09:44
【问题描述】:

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

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

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

分组工作正常,但根据排序,分组的顺序不正确。我尝试了许多可能的“修复”但没有成功(例如,将排序/组描述直接添加到CollectionViewSource,在分组之前排序,删除一些排序/分组,删除SortDescriptions 每个CollectionViewSource does not re-sort on property change) .

有没有人知道如何维护排序顺序而不管执行了多少查询?如果可行的话,我愿意接受在DataGrid 中显示数据的其他查询方法。

【问题讨论】:

  • 我会尝试将 Source 绑定一次(不是分配,绑定,使用 Binding 类的实例)到一个 ObservableCollection&lt;T&gt; 属性,当你给它一个新的时它会引发 PropertyChanged收藏。然后通过更改属性重新填充。要么折腾一个新的集合,要么清除并重新填充旧的集合。但千万不要碰cvsRS.Source,除非最初设置Binding
  • 希望我正确地解释了这一点,我在构造函数中这样做了:cvsRS = new CollectionViewSource(); cvsRS.Source = new Binding("RS"); RSView = cvsRS.View; 但我收到一个错误:'System.Windows.Data.Binding' 不是属性'Source' 的有效值。
  • 我做了一个快速测试,它按预期工作,所以我发布了一个答案,其中包含如何进行绑定的示例。无论如何,将其粘贴到评论中是不可读的。

标签: c# wpf entity-framework sorting icollectionview


【解决方案1】:

尝试将您的 CollectionViewSource.Source 属性绑定到您的 ObservableCollection&lt;T&gt; 属性。在 viewmodel 构造函数中设置绑定。然后,别管它。更新ObservableCollection&lt;T&gt;,替换它等等。只要它是一个ObservableCollection&lt;T&gt;,并且它的公共属性在你替换它时引发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() 时,它在不参考组的情况下使用它们。不知道我明白它在那里做什么。

【讨论】:

  • 谢谢埃德。我已经实现了上面的代码,但是我的DataGrid 现在从不显示任何数据。它的ItemsSource 绑定到RSView。我还保持我的 QueryDatabase 方法相同,除了删除 cvsRS.Source = RS; RSView = cvsRS.View;
  • 现在尝试 RS.Clear() 并向其中添加项目,而不是创建新集合。
  • @matthew_b Ohhhh - 我忘记了另一件事,当事情发生变化时可能需要 RSView.Refresh()。
  • 是的,这是必要的(刚刚测试过),尽管我已经实现了。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-09
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多