Disparar un valor de checkbox cambió el evento en DataGridView

Tengo una vista de cuadrícula que tiene una columna de checkbox, y deseo activar un evento de dibujo tan pronto como se alterne el valor de la celda. Probé el ValueChaged y el CellEndEdit y BeginEdit, y elegí el modo de selección como CellSelect. En cuanto a los primeros 2 eventos, el evento se activó al finalizar el modo de edición, como salir de la celda actual o ir y venir. Es solo un comportamiento extraño.

¿Hay algo que active el evento en la vista de la cuadrícula tan pronto como se cambie el valor de la celda?

Atentamente,

Un colega mío recomienda atrapar el evento CurrentCellDirtyStateChanged. Consulte http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx .

Uso el evento CellContentClick, que se asegura de que el usuario haga clic en la checkbox. SÍ dispara varias veces incluso si el usuario permanece en la misma celda. El único problema es que el valor no se actualiza, y siempre devuelve “falso” para desmarcado. El truco es usar la propiedad .EditedFormattedValue de la celda en lugar de la propiedad Value. EditedFormattedValue hará un seguimiento con la marca de verificación y es lo que uno desea que tenga el valor cuando se active el CellContentClick.

No hay necesidad de un temporizador, no hay necesidad de cosas sofisticadas, solo use el evento CellContentClick e inspeccione el EditedFormattedValue para indicar en qué estado va la entrada / recién ingresada. Si EditedFormattedValue = true, se marca la checkbox.

Otra forma es manejar el evento CellContentClick (que no le proporciona el valor actual en la propiedad Value de la celda), llamar a grid.CommitEdit (DataGridViewDataErrorContexts.Commit) para actualizar el valor que a su vez activará CellValueChanged, donde podrá obtener el valor real (es decir, correcto) DataGridViewCheckBoxColumn.

private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e) { grid.CommitEdit(DataGridViewDataErrorContexts.Commit); } private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e) { // do something with grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value } 

Target .NET framework: 2.0

Intenta conectarte al evento CellContentClick. DataGridViewCellEventArgs tendrá un ColumnIndex y un RowIndex para que pueda saber si se hizo clic en ChecboxCell. Lo bueno de este evento es que solo se activará si se hizo clic en la checkbox real. Si hace clic en el área blanca de la celda alrededor de la checkbox, no se disparará. De esta forma, está prácticamente garantizado que el valor de la checkbox cambió cuando se desencadena este evento. A continuación, puede invocar Invalidate () para desencadenar su evento de dibujo, así como una llamada a EndEdit () para activar el final de la edición de la fila si así lo necesita.

Finalmente lo implementé de esta manera

  private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) { if (e.ColumnIndex >= 0 && e.RowIndex >= 0) { if (dataGridView1[e.ColumnIndex, e.RowIndex].GetContentBounds(e.RowIndex).Contains(e.Location)) { cellEndEditTimer.Start(); } } } private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) { /*place your code here*/} private void cellEndEditTimer_Tick(object sender, EventArgs e) { dataGridView1.EndEdit(); cellEndEditTimer.Stop(); } 

Tuve el mismo problema, pero se me ocurrió una solución diferente:

Si convierte la columna o toda la cuadrícula en “Solo lectura” para que cuando el usuario haga clic en la casilla no cambie el valor.

Afortunadamente, el evento DataGridView.CellClick todavía está activado. En mi caso, hago lo siguiente en el evento cellClick :

 if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell") 

Pero puede verificar el nombre de la columna si tiene más de una columna de checkbox.

Luego hago toda la modificación / guardado del conjunto de datos.

Pequeña actualización … Asegúrate de usar EditedFormattedValue lugar de value ya que probé value pero nunca da el estado correcto que está marcado / desactivado. La mayoría del sitio aún usa value pero como se usa en la última versión de c. 2010 express es una forma de acceder ..

 grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue 

También el evento _CellValueChanged sugerido o usado por pocos debe ser utilizable para algunos casos, pero si está buscando cada check / uncheck of cell asegúrese de usar _CellContentClick else según mi aviso, no veo cada vez que se _CellValueChanged … es decir, si el mismo checkbox se hace clic una y otra vez no se dispara _CellValueChanged pero si hace clic alternativamente, por ejemplo, tiene dos chekbox y haga clic en uno después de otro _CellValueChanged evento se disparará, pero por lo general si busca evento para disparar cada vez que cualquier casilla es check / uncheck _CellValueChanged no está despedido

cellEndEditTimer.Start ();

esta línea hace que datagridview actualice la lista de casillas marcadas

Gracias.

El evento “EditingControlShowing” no se activa al cambiar el valor de la checkbox. Porque el estilo de visualización de la checkbox no cambia.

La solución alternativa que he utilizado es la siguiente. (He utilizado el evento CellContentClick)

  private void gGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (string.Compare(gGridView1.CurrentCell.OwningColumn.Name, "CheckBoxColumn") == 0) { bool checkBoxStatus = Convert.ToBoolean(gGridView1.CurrentCell.EditedFormattedValue); //checkBoxStatus gives you whether checkbox cell value of selected row for the //"CheckBoxColumn" column value is checked or not. if(checkBoxStatus) { //write your code } else { //write your code } } } 

Lo anterior funcionó para mí. Por favor, hágamelo saber si necesita más ayuda.

Encontré una solución simple.

Simplemente cambie el foco de la celda luego de hacer clic en la celda.

 private void DGV_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex == "Here checkbox column id or name") { DGV.Item(e.ColumnIndex, e.RowIndex + 1).Selected = true; //Here your code } } 

No olvide verificar si la columna de su índice (ckeckbox + 1) existe.

Encontré una combinación de las dos primeras respuestas que me dieron lo que necesitaba. Usé el evento CurrentCellDirtyStateChanged e inspeccioné EditedFormattedValue.

 private void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e) { DataGridView dgv = (DataGridView)sender; DataGridViewCell cell = dgv.CurrentCell; if (cell.RowIndex >= 0 && cell.ColumnIndex == 3) // My checkbox column { // If checkbox checked, copy value from col 1 to col 2 if (dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue != null && dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue.Equals(true)) { dgv.Rows[cell.RowIndex].Cells[1].Value = dgv.Rows[cell.RowIndex].Cells[2].Value; } } } 

Use este código cuando desee usar el evento checkedChanged en DataGrid View:

 private void grdBill_CellContentClick(object sender, DataGridViewCellEventArgs e) { grdBill.CurrentCell = grdBill.Rows[grdBill.CurrentRow.Index].Cells["gBillNumber"]; } private void grdBill_CellEndEdit(object sender, DataGridViewCellEventArgs e) { calcBill(); } private void calcBill() { listBox1.Items.Clear(); for (int i = 0; i < grdBill.Rows.Count - 1; i++) { if (Convert.ToBoolean(grdBill.Rows[i].Cells["gCheck"].Value) == true) { listBox1.Items.Add(grdBill.Rows[i].Cells["gBillNumber"].Value.ToString()); } } } 

Aquí, grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox en cuadrícula (segunda columna).

Por lo tanto, cuando deseamos activar el evento changechanged para cada clic, primero haga CellContentClick, se activará cuando el usuario haga clic en el cuadro de texto, luego moverá la celda actual a la siguiente columna, por lo que la columna CellEndEdit recibirá un aviso. si la checkbox está marcada y agregue el "gBillNumber" en el cuadro de lista (en la función calcBill).

Al trabajar con un control independiente (es decir, administro el contenido mediante progtwigción), sin EndEdit () solo se llama CurrentCellDirtyStateChanged una vez y luego nunca más; pero encontré que con el EndEdit () se llamó dos veces a CurrentCellDirtyStateChanged (el segundo probablemente causado por el EndEdit () pero no lo verifiqué), así que hice lo siguiente, que funcionó mejor para mí:

  bool myGridView_DoCheck = false; private void myGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e) { if (!myGridView_DoCheck) { myGridView_DoCheck = true; myGridView.EndEdit(); // do something here } else myGridView_DoCheck = false; } 

Cada una de las respuestas de CellClick y CellMouseClick es incorrecta, porque puede cambiar el valor de la celda con el teclado y el evento no se activará. Además, CurrentCellDirtyStateChanged solo se activa una vez, lo que significa que si marcas o desmarcas la misma casilla varias veces, solo obtendrás un evento. Combinando algunas de las respuestas anteriores se obtiene la siguiente solución simple:

 private void dgvList_CurrentCellDirtyStateChanged(object sender, EventArgs e) { if (dgvList.CurrentCell is DataGridViewCheckBoxCell) dgvList.CommitEdit(DataGridViewDataErrorContexts.Commit); } private void dgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e) { // Now this will fire immediately when a check box cell is changed, // regardless of whether the user uses the mouse, keyboard, or touchscreen. // // Value property is up to date, you DO NOT need EditedFormattedValue here. }