We currently have a DataGrid
that is bound to a DataTable
. It also has a template column with a CheckBox
in it that we add in programatically. This purpose of this column is track multiple selections in the DataGrid
.
A factory is used to create the CheckBox
es for each row.
There are quite a few records, so row virtualization is set to true so that the performance is acceptable. However, we're seeing a strange issue where if we check some CheckBox
es on the first 10 rows and then scroll down about 50 rows (the grid has about 10 rows visible at any one time), there are a bunch of other CheckBox
es that appear to be checked at random.
If we disable row virtualization this problem does not exist (but the performance is terrible). Is there any way around this? Anyone know what we may be doing wrong?
If you turned on Virtualization because the datagrid loading time is terrible, then, here's the solution:
let's assume/call your datagrid's items source binding as "Rows",
Add a property to your "Row" class IsVisible and toggle it when you want to load the data (not when UI thread decides to resolve the binding and load each control)
the reason this works, is because when you load the grid, it checks the binding, all row are invisible, so the UI thread doesn't have to spin through all your rows*columns to create them, it can go to the next thing it needs to do. You on the other hand, can detect when is convenient time to turn those rows into visible, when the View.Visibility is visible, when the ViewModel loaded the data from somewhere, etc. So you are in total control. Below I am iterating through my item source (rows) using a task (in a background thread), yet setting Visibility on the UI thread.
In the View, when datagrid is loading don't allow it to hog the UI thread by putting the iteration of rows in the background thread, then set the Visibility to true. Even though you're on the background thread, IsVisible property changed will trigger you to update.
forgot to add ExeOnUi code (you might check access using something else like whateverControl.Dispatcher.CheckAccess, I just use Microsoft.Practices.ServiceLocator):
If you are looking for speed ListView Gridview is much much faster (and has less features).
Try disable container recycling.
I just run into similar problem and its resolved after adding
UpdateSourceTrigger=PropertyChanged
to the binding.