How to detect DataGridView CheckBox event change?
To handle the DatGridView
s CheckedChanged
event you must first get the CellContentClick
to fire (which does not have the CheckBox
es current state!) then call CommitEdit
. This will in turn fire the CellValueChanged
event which you can use to do your work. This is an oversight by Microsoft. Do some thing like the following...
private void dataGridViewSites_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
dataGridViewSites.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
/// <summary>
/// Works with the above.
/// </summary>
private void dataGridViewSites_CellValueChanged(object sender,
DataGridViewCellEventArgs e)
{
UpdateDataGridViewSite();
}
P.S. Check this article https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged(v=vs.110).aspx
C# DataGridView Checkbox checked event
You can handle CellContentClick
event of your DataGridView
and put the logic for changing those cells there.
The key point is using CommitEdit(DataGridViewDataErrorContexts.Commit)
to commits changes in the current cell to the data cache without ending edit mode. This way when you check for value of cell in this event, it returns current checked or unchecked value which you see in the cell currently after click:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//We make DataGridCheckBoxColumn commit changes with single click
//use index of logout column
if(e.ColumnIndex == 4 && e.RowIndex>=0)
this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
//Check the value of cell
if((bool)this.dataGridView1.CurrentCell.Value == true)
{
//Use index of TimeOut column
this.dataGridView1.Rows[e.RowIndex].Cells[3].Value = DateTime.Now;
//Set other columns values
}
else
{
//Use index of TimeOut column
this.dataGridView1.Rows[e.RowIndex].Cells[3].Value = DBNull.Value;
//Set other columns values
}
}
Datagridview checkbox checked when clicking the cell
As Bioukh points out, you must call NotifyCurrentCellDirty(true)
to trigger your event handler. However, adding that line will no longer update your checked state. To finalize your checked state change on click we'll add a call to RefreshEdit
. This will work to toggle your cell checked state when the cell is clicked, but it will also make the first click of the actual checkbox a bit buggy. So we add the CellContentClick
event handler as shown below and you should be good to go.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCheckBoxCell cell = this.dataGridView1.CurrentCell as DataGridViewCheckBoxCell;
if (cell != null && !cell.ReadOnly)
{
cell.Value = cell.Value == null || !((bool)cell.Value);
this.dataGridView1.RefreshEdit();
this.dataGridView1.NotifyCurrentCellDirty(true);
}
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
this.dataGridView1.RefreshEdit();
}
DataGridView event for checked change
In the CurrentCellDirtyStateChanged
event handler, trigger EndEdit
so that the value changed event is triggered.
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty && dataGridView1.CurrentCell.ColumnIndex == CheckColumnIndex)
{
dataGridView1.EndEdit();
}
}
In the CellValueChanged
event handler get the value from the CheckBoxColumn.
void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == CheckColumnIndex)
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
bool achecked = Convert.ToBoolean(checkCell.Value);
}
}
DataGridViewCheckBox cell check event in WinForms
First you need to set DataGridViewCheckBoxColumn TrueValue and FalseValue properties. Then you should handle DataGridView CellContentClick and CellValueChanged, in order to determine whether the cell is checked or not.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var checkBoxColumn = (DataGridViewCheckBoxColumn)this.dataGridView1.Columns[0];
checkBoxColumn.TrueValue = true;
checkBoxColumn.FalseValue = false;
this.dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
this.dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCheckBoxCell cell = (sender as DataGridView).Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewCheckBoxCell;
if (cell != null)
{
if (cell.Value == cell.TrueValue)
{
MessageBox.Show("Cell checked.");
}
else
{
MessageBox.Show("Cell unchecked.");
}
}
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var dataGridView = sender as DataGridView;
if (dataGridView.Columns[e.ColumnIndex] is DataGridViewCheckBoxColumn)
{
// Raise CellValueChanged
dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
}
C# Datagridview Checkbox Checked Event - multiple rows?
On button Click event do:
static int SelectColumnIndex = 0;
PerformAction_Click(object sender, System.EventArgs e)
{
string data = string.Empty;
foreach(DataGridViewRow row in MyDataGridView.Rows)
{
if(row.Cells[SelectColumnIndex].Value!=null &&
Convert.ToBoolean(row.Cells[SelectColumnIndex].Value) == true)
{
foreach(DataGridViewCell cell in row.Cells)
{
if(cell.OwningColumn.Index!= SelectColumnIndex)
{
data+= (cell.Value + " ") ; // do some thing
}
}
data+="\n";
}
}
MessageBox.Show(data, "Data");
}
CheckBox checked event is raised when I scroll down datagrid
As Manfred said in the comments, I just need to care of my ViewModel to fix this. This unexpected behavior occurred because I was using dataTrigger for checking and unchecking Checkbox.Instead I should use viewModel to bind my checkbox to itemsource.
Here is a good example of using checkbox in datagrid
and here is a good expalnation of MVVM pattern.
Triggering a checkbox value changed event in DataGridView
A colleague of mine recommends trapping the CurrentCellDirtyStateChanged event. See http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx.
How to cancel a checkbox in a DataGridView from being checked
One possible way is to handle the CurrentCellDirtyStateChanged
event on DataGridView
. Check your condition and ensure the current cell is a CheckBoxCell
then call CancelEdit
if both conditions are met.
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (youShouldCancelCheck &&
this.dataGridView1.IsCurrentCellDirty &&
this.dataGridView1.CurrentCell is DataGridViewCheckBoxCell)
{
this.dataGridView1.CancelEdit();
// Addition code here.
}
}
Edit
I've added an additional condition to the if
statement to check if the cell is dirty before running the CancelEdit
and your additional code. This should no longer run twice. What was happening was:
- User clicks checkbox.
IsCurrentCellDirty = true
andCurrentCellDirtyStateChanged
is fired. - Conditions are met.
CancelEdit
is fired, which cancels all changes and setsIsCurrentCellDirty = false
. ThusCurrentCellDirtyStateChanged
is fired again.
CurrentCellDirtyStateChanged
will still be fired twice, but code within the conditional will only be run when dirty.
Related Topics
PDF Compression with Itextsharp
How to Quickly Up-Cast Object[,] into Double[,]
Easier Way of Writing Null or Empty
C# Datagridview Checkbox Checked Event
When Would You Use Delegates in C#
Most Efficient Method of Self Referencing Tree Using Entity Framework
Why Use Asqueryable() Instead of List()
How to Navigate a Few Folders Up
How to Create Migrations After Upgrading to ASP.NET Core 2.0
A Textbox/Richtextbox That Has Syntax Highlighting? [C#]
Curiously Recurring Template Pattern and Generics Constraints (C#)
"Requested Uri Is Invalid" During Upload with Ftpwebrequest
Does C# Allow Double Semicolon ; ; If So, Are There Any Special Ways
When Should I Choose Inheritance Over an Interface When Designing C# Class Libraries
Case Insensitive Access for Generic Dictionary