I am seeing an anomaly in the display of check box controls in a
DataGridView. I am able to programmatically set the check box state for each
row in the DataGridView. However, for the currently selected row the change
in state does not get reflected in the UI. Here is the relevant code that
sets up the controls:
DataGridView dataGridViewDocument = new DataGridView();
// Only allow one row in the DataGridView to be selected at a time.
dataGridViewDocument.MultiSelect = false;
. . .
// Add a check box column to the DataGridView by
// creating a DataColumn and adding it to the DataSet.
DataColumn dataColumn = new DataColumn();
dataColumn.DataType = System.Type.GetType("System.Boolean");
dataColumn.AllowDBNull = false;
dataColumn.Caption = "selected";
dataColumn.ColumnName = "CheckBox";
dataColumn.DefaultValue = 0;
// Add the data column to the data set before setting the data source.
dataSetSearchResults.Tables[FastDoc.FWHSearch].Columns.Add(dataColumn);
dataGridViewDocument.DataSource =
dataSetSearchResults.Tables[FastDoc.FWHSearch];
Here is code that manifests the problem:
bool IsToBeChecked = true;
foreach (DataGridViewRow dataGridViewRow in this.dataGridViewDocument.Rows)
{
dataGridViewRow.Cells["CheckBox"].Value = IsToBeChecked;
}
If all of the rows start off unchecked, after the loop iterates through all
of the rows, the check box will appear checked for all of the rows except for
the currently selected row. The opposite is true for starting off with all
checkboxes checked and attempting to clear all of the check boxes; after the
loop completes, all of the check boxes appear unchecked except for the
currently selected row.
Here is some additional information. When I run the program in the
debugger, I can confirm that the actual value of
dataGridViewRow.Cells["CheckBox"].Value gets correctly set to the value of
IsToBe checked. The change simply doesn't appear in the UI for the currently
selected row. If I change the state of the check box of the selected row by
manually clicking on it, the check box properly toggles between being checked
and unchecked.
As a test, I modified the code to temporarily unselect and reselect the
currently selected row:
if (dataGridViewRow.Cells["CheckBox"].Selected)
{
dataGridViewRow.Cells["CheckBox"].Selected = false;
dataGridViewRow.Cells["CheckBox"].Value = IsToBeChecked;
dataGridViewRow.Cells["CheckBox"].Selected = true;
}
This change caused the bug to go away. The check boxes in all rows
including the currently selected row were updated in the UI with the correct
state; however, this is not a good workaround in that the act of unselecting
and reselecting a row causes the OnSelectionChanged event handler for the
DataGridView to run with undesirable side effects. I could set a global flag
and modify the event handler to detect when it has been triggered by the
above code and skip processing but that is messy. I would rather just get
the code that updates the check box to update the UI as expected.
I am running Visual Studio 2008 SP1 with the .NET Framework 3.5 SP1.
Does anyone have any ideas as to why it might be happening or have any ideas
how to fix it? Thanks.
-Bruce
I'm afraid I am unable to reproduce your problem. Both when using a
DataTable, filling it with data and afterwards adding the CheckBox column,
and when using business objects as datasource it will happily update all the
CheckBoxes using your loop. Including for fullrow and/or multiselect. I'm
suspecting your dataset is somewhat complex and the real problem lies within
the dataset/datatable.
Does this code work as expected?
DataGridView dataGridViewDocument = new DataGridView();
public Form1()
{
InitializeComponent();
Controls.Add(dataGridViewDocument);
// Only allow one row in the DataGridView to be selected at a time.
dataGridViewDocument.MultiSelect = false;
List<MyClass> list = new List<MyClass> {
new MyClass { Selected = false },
new MyClass { Selected = false },
new MyClass { Selected = false },
new MyClass { Selected = false }
};
dataGridViewDocument.DataSource = list;
}
class MyClass
{
public bool Selected { get; set; }
}
bool IsToBeChecked = true;
public void button_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow dataGridViewRow in
this.dataGridViewDocument.Rows)
{
dataGridViewRow.Cells["Selected"].Value = IsToBeChecked;
}
IsToBeChecked = !IsToBeChecked;
}
--
Happy Coding!
Morten Wennevik [C# MVP]
I tried using your code and I was unable to reproduce the anomaly. You were
right about the issue being related to having the data originate from a
DataSet. I tried systematically adding functionality from my program to the
test program and the problem returned when I set the DataGridView.DataSource
to be my DataSet rather than the generic list class.
The issue appears to be related to having the currently selected row in an
editing mode. The fix, discovered by trial and error with available
properties, was to explicitly begin and end editing mode when setting the
value for the currently selected row:
if (dataGridViewRow.Cells["CheckBox"].Selected)
{
dataGridViewDocument.BeginEdit(false);
}
dataGridViewRow.Cells["CheckBox"].Value = IsToBeChecked;
if (dataGridViewRow.Cells["CheckBox"].Selected)
{
dataGridViewDocument.EndEdit();
}
With the above code change the problem goes away. Thanks for your help.
-Bruce
>>> On Sunday, April 05, 2009 4:43 PM Bruc wrote:
>>> Morten,
>>>
>>> I tried using your code and I was unable to reproduce the anomaly. You were
>>> right about the issue being related to having the data originate from a
>>> DataSet. I tried systematically adding functionality from my program to the
>>> test program and the problem returned when I set the DataGridView.DataSource
>>> to be my DataSet rather than the generic list class.
>>>
>>> The issue appears to be related to having the currently selected row in an
>>> editing mode. The fix, discovered by trial and error with available
>>> properties, was to explicitly begin and end editing mode when setting the
>>> value for the currently selected row:
>>>
>>> if (dataGridViewRow.Cells["CheckBox"].Selected)
>>> {
>>> dataGridViewDocument.BeginEdit(false);
>>> }
>>> dataGridViewRow.Cells["CheckBox"].Value = IsToBeChecked;
>>> if (dataGridViewRow.Cells["CheckBox"].Selected)
>>> {
>>> dataGridViewDocument.EndEdit();
>>> }
>>>
>>> With the above code change the problem goes away. Thanks for your help.
>>>
>>> -Bruce
>>>
>>> "Morten Wennevik [C# MVP]" wrote:
>>> Submitted via EggHeadCafe - Software Developer Portal of Choice
>>> Changing WCF Service Implementation at Runtime
>>> http://www.eggheadcafe.com/tutorials/aspnet/d9263dcc-f7ed-42f3-bc96-321461be3306/changing-wcf-service-implementation-at-runtime.aspx
> On Thursday, April 02, 2009 4:15 PM Bruc wrote:
>> On Friday, April 03, 2009 4:12 AM MortenWennevi wrote:
>> Hi Bruce,
>>
>> I'm afraid I am unable to reproduce your problem. Both when using a
>> DataTable, filling it with data and afterwards adding the CheckBox column,
>> and when using business objects as datasource it will happily update all the
>> CheckBoxes using your loop. Including for fullrow and/or multiselect. I'm
>> suspecting your dataset is somewhat complex and the real problem lies within
>> the dataset/datatable.
>>
>> Does this code work as expected?
>>
>> DataGridView dataGridViewDocument = new DataGridView();
>> public Form1()
>> {
>> InitializeComponent();
>>
>>
>> Controls.Add(dataGridViewDocument);
>>
>> // Only allow one row in the DataGridView to be selected at a time.
>> dataGridViewDocument.MultiSelect = false;
>>
>> List<MyClass> list = new List<MyClass> {
>> new MyClass { Selected = false },
>> new MyClass { Selected = false },
>> new MyClass { Selected = false },
>> new MyClass { Selected = false }
>> };
>> dataGridViewDocument.DataSource = list;
>> }
>>
>> class MyClass
>> {
>> public bool Selected { get; set; }
>> }
>>
>> bool IsToBeChecked = true;
>> public void button_Click(object sender, EventArgs e)
>> {
>> foreach (DataGridViewRow dataGridViewRow in
>> this.dataGridViewDocument.Rows)
>> {
>> dataGridViewRow.Cells["Selected"].Value = IsToBeChecked;
>> }
>> IsToBeChecked = !IsToBeChecked;
>> }
>>
>> --
>> Happy Coding!
>> Morten Wennevik [C# MVP]
>>
>>
>> "Bruce" wrote:
>>> On Sunday, April 05, 2009 4:43 PM Bruc wrote:
>>> Morten,
>>>
>>> I tried using your code and I was unable to reproduce the anomaly. You were
>>> right about the issue being related to having the data originate from a
>>> DataSet. I tried systematically adding functionality from my program to the
>>> test program and the problem returned when I set the DataGridView.DataSource
>>> to be my DataSet rather than the generic list class.
>>>
>>> The issue appears to be related to having the currently selected row in an
>>> editing mode. The fix, discovered by trial and error with available
>>> properties, was to explicitly begin and end editing mode when setting the
>>> value for the currently selected row:
>>>
>>> if (dataGridViewRow.Cells["CheckBox"].Selected)
>>> {
>>> dataGridViewDocument.BeginEdit(false);
>>> }
>>> dataGridViewRow.Cells["CheckBox"].Value = IsToBeChecked;
>>> if (dataGridViewRow.Cells["CheckBox"].Selected)
>>> {
>>> dataGridViewDocument.EndEdit();
>>> }
>>>
>>> With the above code change the problem goes away. Thanks for your help.
>>>
>>> -Bruce
>>>
>>> "Morten Wennevik [C# MVP]" wrote:
>>>> On Monday, August 16, 2010 2:32 AM A Trojan wrote:
>>>> thanks a lot , that works fine for me
>>>> Submitted via EggHeadCafe
>>>> ASP.NET Drawing a chart using OWC11 - Office Web Components
>>>> http://www.eggheadcafe.com/tutorials/aspnet/601e9bc2-40ed-405e-b1b0-f416046b6698/aspnet-drawing-a-chart-using-owc11--office-web-components.aspx
> On Thursday, April 02, 2009 4:15 PM Bruc wrote:
>> On Friday, April 03, 2009 4:12 AM MortenWennevi wrote:
>> Hi Bruce,
>>
>> I'm afraid I am unable to reproduce your problem. Both when using a
>> DataTable, filling it with data and afterwards adding the CheckBox column,
>> and when using business objects as datasource it will happily update all the
>> CheckBoxes using your loop. Including for fullrow and/or multiselect. I'm
>> suspecting your dataset is somewhat complex and the real problem lies within
>> the dataset/datatable.
>>
>> Does this code work as expected?
>>
>> DataGridView dataGridViewDocument = new DataGridView();
>> public Form1()
>> {
>> InitializeComponent();
>>
>>
>> Controls.Add(dataGridViewDocument);
>>
>> // Only allow one row in the DataGridView to be selected at a time.
>> dataGridViewDocument.MultiSelect = false;
>>
>> List<MyClass> list = new List<MyClass> {
>> new MyClass { Selected = false },
>> new MyClass { Selected = false },
>> new MyClass { Selected = false },
>> new MyClass { Selected = false }
>> };
>> dataGridViewDocument.DataSource = list;
>> }
>>
>> class MyClass
>> {
>> public bool Selected { get; set; }
>> }
>>
>> bool IsToBeChecked = true;
>> public void button_Click(object sender, EventArgs e)
>> {
>> foreach (DataGridViewRow dataGridViewRow in
>> this.dataGridViewDocument.Rows)
>> {
>> dataGridViewRow.Cells["Selected"].Value = IsToBeChecked;
>> }
>> IsToBeChecked = !IsToBeChecked;
>> }
>>
>> --
>> Happy Coding!
>> Morten Wennevik [C# MVP]
>>
>>
>> "Bruce" wrote:
>>> On Sunday, April 05, 2009 4:43 PM Bruc wrote:
>>> Morten,
>>>
>>> I tried using your code and I was unable to reproduce the anomaly. You were
>>> right about the issue being related to having the data originate from a
>>> DataSet. I tried systematically adding functionality from my program to the
>>> test program and the problem returned when I set the DataGridView.DataSource
>>> to be my DataSet rather than the generic list class.
>>>
>>> The issue appears to be related to having the currently selected row in an
>>> editing mode. The fix, discovered by trial and error with available
>>> properties, was to explicitly begin and end editing mode when setting the
>>> value for the currently selected row:
>>>
>>> if (dataGridViewRow.Cells["CheckBox"].Selected)
>>> {
>>> dataGridViewDocument.BeginEdit(false);
>>> }
>>> dataGridViewRow.Cells["CheckBox"].Value = IsToBeChecked;
>>> if (dataGridViewRow.Cells["CheckBox"].Selected)
>>> {
>>> dataGridViewDocument.EndEdit();
>>> }
>>>
>>> With the above code change the problem goes away. Thanks for your help.
>>>
>>> -Bruce
>>>
>>> "Morten Wennevik [C# MVP]" wrote:
>>>> On Monday, August 16, 2010 2:32 AM A Trojan wrote:
>>>> thanks a lot , that works fine for me
>>>>> On Monday, January 17, 2011 7:05 AM Pramit Bohidar wrote:
>>>>> Use RefreshEdit() method after setting the value for the checkbox to True or False. It will change the state automatically in the grid.
>>>>> Submitted via EggHeadCafe
>>>>> ASP.NET GridView Persist User-Selected CheckBox Values
>>>>> http://www.eggheadcafe.com/tutorials/aspnet/58db18a0-fcd6-43d2-954a-ae076427b739/aspnet-gridview-persist-userselected-checkbox-values.aspx