0

我有一个使用 GroupBy 的 LINQ 查询的结果,我已绑定到 DataGridView。我必须实现什么,底层 IEnumerable List 中的更改将导致 DataGridView 刷新?

我发现的简单方法是在发生变化时重新执行查询并将查询重新绑定到 datagridview。这可行,尽管有一些副作用(用户选择的项目被取消选择 - 列表滚动到顶部)。我猜这是因为 DataGridView 实际上得到了一个绑定到它的完整新列表,而不仅仅是一条已更新的记录。有没有办法更有效地实现更新行为?

也许 Linq 不是有效地做到这一点的正确方法。如果我不必编写 10 个类来完成它,我也愿意接受其他解决方案。

    private void BindObjectsToDataGridView()
    {
        IEnumerable<Telegram> myTelegrams = Source.GetTelegrams();
        myDataGridView.DataSource = myTelegrams.GroupBy(g => g.ID)
                                               .Select(s => new { ID = s.ID, Count = s.Count() })
                                               .ToList();
    }

    private void Source_TelegramsChanged(object sender, EventArgs e)
    {   
        // Just rebinding the Linq updates just fine
        // but it causes user-side issues in the datagrid view.
        // And it feels wrong to completely rebuild the list when
        // only one telegram has been changed/added/removed...
        BindObjectsToDataGridView();
    }
4

1 回答 1

1

简短的回答:为您的行提供一个单独的 ViewModel 类,并在您的主 ViewModel 中使用这些行 ViewModel 的 ObservableCollection。

长答案: ViewModel 行维护对公开的 Telegram Model 对象的引用。主 ViewModel 具有行 ViewModel 的 ObservableCollection。主 ViewModel 应该对行进行增量更新 - 很容易,因为我确信每个 Telegram 对象都有唯一的 ID。您的行 ViewModel 类将网格绑定单元格值公开为 INotifyPropertyChanged 属性。这样,可以检测到更改,而不是通过昂贵的“重绘所有内容”过程,可以通过 INotifyPropertyChanged 调用更新单个属性。

此外,为了避免以后意外绑定集合覆盖问题,请将 ObservableCollection 行的设置器设为私有设置器。

于 2013-09-10T08:32:38.697 回答