Reputation: 3307
I have a result of a LINQ query with GroupBy which I have bound to a DataGridView. What will I have to implement, that changes in the underlying IEnumerable List will cause the DataGridView to refresh?
The easy way I have found is to just reexecute and rebind the query to the datagridview whenever something changes. This works, although with some sideeffects (user selected items get deselected - list scrolls to top). I guess this is because the DataGridView gets actually a complete new list bound to it and not just a single record that has updated. Is there a way to implement the update behaviour more efficiently?
Maybe Linq is not the correct way to do this efficiently. I'm open to other solutions as well, if I don't have to write 10 classes to accomplish it.
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();
}
Upvotes: 0
Views: 427
Reputation: 7944
Short answer: Have a separate ViewModel class for your row with an ObservableCollection of these row ViewModels in your main ViewModel.
Long answer: The row ViewModel maintains the reference to the exposed Telegram Model object. The main ViewModel has an ObservableCollection of the row ViewModels. The main ViewModel should do incremental updates of the rows - easy enough to as I'm sure you have unique IDs for each Telegram object. Your row ViewModel class exposes the grid-bound cell values as INotifyPropertyChanged properties. This way, changes can be detected and rather than going through the expensive "redraw everything" process, a single property can be updated through an INotifyPropertyChanged call.
Also to avoid accidental bound collection overwrite issues later, make the setter of your ObservableCollection of rows, a private setter.
Upvotes: 1