I am using checkbox
in an itemtemplate
column in a Silverlight 5 DataGrid.
I am facing a strange problem with it. When I select more than
This is a known behaviour since Silverlight is re-using its graphical resources in the DataGrid. There's a discussion about it in this Silverlight thread.
It seems one way to fix it is to databind the IsSelected property:
My solution at that time was to add a new property in my data source: IsSelected, and to bind the checkbox to that value.
You have more additional info in this thread, where Microsoft answers:
This is not a bug. What happens when you scroll around in the DataGrid is the same checkboxes are being used for new data because the DataGrid recycles the visuals. When your new data has different values, the check will change through the Binding and you'll receive the event. What you can do to get this scenario to work is to listen to LoadingRow which is raised when a row comes into view. In there, you can call column.GetCellContents to get the contents of the cell. This will give you the CheckBox, and you can attach to CheckChanged at this time. If you do this, you need to do something similar and listen to UnloadingRow so you can detach the eventhandler when the checkbox is scrolled out of view.
I fixed this problem in my code. I did handling within the LoadingRow and UnloadingRow events of the grid. As soon as a row is loaded, we need to look for the condition on the basis of which we want to keep the check-box checked or unchecked. But as soon as you set the IsChecked property, Checked or UnChecked event of the check-box will get fired. In this scenario we can unregister the Checked and UnChecked events of the check-box if we have any, set the IsChecked property. After setting this, again register the events.
Below is the code for your help.
Add LoadingRow and UnloadingRow events to your grid.
... LoadingRow="DGUserList_RowLoadUnload" UnloadingRow="DGUserList_RowLoadUnload">
In your code behind file:
private void DGUserList_RowLoadUnload(object sender, DataGridRowEventArgs e)
{
DataGridRow row = e.Row;
CheckBox cbox = (CheckBox)this.dgUserList.Columns[0].GetCellContent(row);
this.UpdateHookedEventsForCheckBox(cbox, false);
cbox.IsChecked = true; // Here put your condition for check/uncheck
this.UpdateHookedEventsForCheckBox(cbox, true);
}
private void UpdateHookedEventsForCheckBox(CheckBox chkBox, bool register)
{
if (register)
{
chkBox.Checked += this.CheckBox_Checked;
chkBox.Unchecked += this.CheckBox_Unchecked;
}
else
{
chkBox.Checked -= this.CheckBox_Checked;
chkBox.Unchecked -= this.CheckBox_Unchecked;
}
}
This way I need not bother about putting some hake code in my Checked and UnChecked events.