刷新绑定Linq结果到datagridview

时间:2013-09-10 07:37:23

标签: c# winforms linq binding datagridview

我有一个带有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();
    }

1 个答案:

答案 0 :(得分:1)

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

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

另外,为避免意外绑定集合覆盖问题,请将ObservableCollection行的setter设为私有setter。