我有一个带有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();
}
答案 0 :(得分:1)
简短回答:为您的行创建一个单独的ViewModel类,并在主ViewModel中使用这些行ViewModel的ObservableCollection。
答案很长: 行ViewModel维护对公开的Telegram Model对象的引用。主ViewModel具有ViewModels行的ObservableCollection。主ViewModel应该对行进行增量更新 - 这很容易,因为我确信每个Telegram对象都有唯一的ID。您的行ViewModel类将网格绑定的单元格值公开为INotifyPropertyChanged属性。这样,可以检测到更改,而不是通过昂贵的“重绘所有”过程,可以通过INotifyPropertyChanged调用更新单个属性。
另外,为避免意外绑定集合覆盖问题,请将ObservableCollection行的setter设为私有setter。