DataGridViewCheckBoxColumn: Detectar el cambio/check en el evento CellValueChanged

Huston… teniamos un problema! Va yo era el del problema. Con un amigo del trabajo Pedro (flamante programador Clipper!) teniamos que realizar acciones en un winform en un control Datagridview con un Checkbox. Simple no? Pero cuando queriamos acceder por codigo al valor de la columna DataGridViewCheckBoxColumn CellValueChanged no teniamos el cambio actual.

Problema

Tenemos una grilla con una columna DataGridViewCheckBoxColumn

image

Para que cuando tengamos evento click en el check…

image

LO PODAMOS DETECTAR !!! Pense que era mas facil de lo que crei, pero por eso aqui esta este instructivo con las dos opciones:

Antes que nada… explicación de porque no podemos hacer simplemente…con los eventos como las otras celdas:
Pero si lo hacemos en el evento CellContentClick, no tendremos actualizado el valor del check 

Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

    MsgBox("Estado: " & Me.DataGridView1.Rows(e.RowIndex).Cells("check").Value)

End Sub

(from MSDN…)CellContentClick: Para los clicks en DataGridViewCheckBoxCell este evento se produce antes de que cambie el valor de la casilla de verificación(…)

Si lo hacemos aqui CellValueChanged (que es donde deberiamos consultar por naturaleza) solo se produce cuando el usuario deja la celda actual. Esto sucede porque los cambios no se plasman hasta luego de ejecutar el evento CellEndEdit.

 

 

OPCION 1: La parte “ortodoxa”… cambiar el estado por nosotros mismos. Tenemos el control

Aqui la idea es cambiar la propiedad de esta columna DataGridViewCheckBoxColumn a ReadOnly

image 

image

Y en el evento CellContentClick, tendremos que ”artesanalmente” cambiar de estado… y alli si podremos recuperarlo.

Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

   If e.ColumnIndex = Me.DataGridView1.Columns.Item("check").Index Then
       Dim chkCell As DataGridViewCheckBoxCell = Me.DataGridView1.Rows(e.RowIndex).Cells("check")
       chkCell.Value = Not chkCell.Value
   End If

   MsgBox("Estado: " & EstadoCheck(e.RowIndex))

End Sub

(Nota: Aqui la columna checkbox se llama “check”, y el metodo EstadoCheck solo obtiene el estado del la columna con el check – para demo)

Entonces? Aqui es una forma ortodoxa de conseguir nuestro objetivo: “Tener un poco de control en el OnClick del checkbox en una columna DataGridViewCheckBoxColumn del Datagridview”

 

 

OPCION 2:  Tener control del cambio en el CheckBoxColumn: Evento CurrentCellDirtyStateChanged (cuando se cambia el estado de alguna celda)

Esta opcion es la recomendacion de MSDN asi que, aqui va…

La columna checkbox (DataGridViewCheckBoxColumn) la dejamos como esta… sin propiedad ReanOnly seteada.

En el evento CurrentCellDirtyStateChanged preguntamos si la celda actual tiene cambios sin confirmar (propiedad IsCurrentCellDirty)

Private Sub DataGridView1_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
       If DataGridView1.IsCurrentCellDirty Then
           DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
       End If
   End Sub

         y alli si podremos consultar el valor… en el evento por naturaleza

Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged

       MsgBox("Estado: " & EstadoCheck(e.RowIndex))

End Sub

 

 

Enlaces:

34 comentarios en “DataGridViewCheckBoxColumn: Detectar el cambio/check en el evento CellValueChanged”

  1. Hola, muy buen tip …me sirvio mucho para implementarlo en un datagrid que estoy haciendo con bases de datos, pero me salta una pequeña duda…sobre el valor EstadoCheck, como se declara para que entregue el mismo valor de Me.DataGridView1.Rows(e.RowIndex).Cells(“check”).Value??? Gracias.

  2. Hola Cristian
    Me alegro que te sirva el articulo.
    La funcion EstadoCheck es una “ayuda” simplemente para tener el codigo mas claro, aqui te dejo la implementacion:

    Private Function EstadoCheck(ByVal filaposicion As Integer) As Boolean
    Return Me.DataGridView1.Rows(filaposicion).Cells(“check”).Value
    End Function

    Saludos.-

  3. Hola, la verdad es que me servido muchisimo, la explicación que has puesto, porque estoy implementando una grid con un checkboxcolumn. Y ahora tengo otro pequeño problema, a ver si me puedes dar alguna idea, porque a mi ya no me viene ninguna.

    En la grid solo quiero que me muestre algunas de las filas de la columna checkbox, es decir, tengo 10 filas pero solo quiero que me muestre el check de las 3 primeras. Sabes como podria hacerlo? He intentado poner esas celdas con valor visible=false, pero visible es de solo lectura. Alguna idea?Espero que me puedas ayudar.

    Saludos
    Patricia

  4. Excelente artículo. Es justo lo que estaba buscando. Probé de mil maneras y no le había encontrado la vuelta.
    Muchas gracias por compartir.

  5. Muy buen ejemplo, busque en muchas páginas y ninguno fue tan claro.
    Modifique un poco el ejemplo para ajustarlo a mi necesidad:
    private void dtgEnsayos_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
    if(e.ColumnIndex == this.dtgEnsayos.Columns[0].Index)
    {
    DataGridViewCheckBoxCell chkCelda = (DataGridViewCheckBoxCell)this.dtgEnsayos.Rows[e.RowIndex].Cells[0];
    if (Convert.ToBoolean(chkCelda.Value)==true)
    {
    chkCelda.Value = false;
    dtgEnsayos.Rows[e.RowIndex].Selected = false;
    }
    else
    {
    chkCelda.Value = true;
    dtgEnsayos.Rows[e.RowIndex].Selected = true;
    }
    }

    }

  6. @WIlmar Cabezas
    Me alegro que te sirva de ayuda o guia.
    Gracias por compartir tu codigo(hace meses que no estoy en proyectos que involucren winform)

  7. anduve varios dias buscando este tipo de solucion.
    mi implementacion utiliza eso si, un datagrid dinamico, asi que tuve que agregar un handler adicional, pero me sirvio mucho el commit
    Gracias!!!!

  8. hola soy nuevo en visual net y estoy realizando una aplicacion el cual necesito selecionar varios cosas de un datagrid con un checkbox y enviar a la base si me pueden ayudar con algun codigo o imagenes de hacer esto gracias

  9. @Hola Fernando
    Si me pueden ayudar? Claro.. solamente que soy yo! en este humilde post
    Hace unos cuantos meses que no utilizo winform, asi que no estoy con todo en mi cabeza.
    Te convendria probar con ejemplos..

    Info sobre el Datagridview
    http://www.windowsclient.net/Samples/Go%20To%20Market/DataGridView/DataGridView%20FAQ.doc

    Post relaciones con Datagridview
    http://windowsclient.net/blogs/faqs/archive/tags/DataGridView/default.aspx

    Tienes un ejemplo de Datagridview aqui:
    http://blogs.windowsclient.net/downloads/folders/applications/entry1304.aspx

    Te proponga luego que te des una vuelta por los foros de MSDN
    http://social.msdn.microsoft.com/Forums/es-ES/categories

    Mira la busqueda:
    http://social.msdn.microsoft.com/Search/es-ES/?Refinement=112&query=Datagridview%20checkbox

    … tambien por supuesto que te des una vuelta por los newsgroups (todavía viven je)
    Ejemplo (vistos desde la UI de google grupos)
    de C#
    http://groups.google.com.ar/group/microsoft.public.es.csharp/topics
    de VB.NET
    http://groups.google.com.ar/group/microsoft.public.es.dotnet.vb/topics

    Espero que te sirva de ayuda o guia

  10. Hola @Roberto
    Gracias por el enlace, solo aclaro que tu enlace es para DataGrid para la web (el ahora Gridview)
    Aqui en este post es sobre el DataGridview para Winform (columna tipo DataGridViewCheckBoxColumn)
    Saludos

  11. Muchas gracias!!!!!!!!! lo probe con la segunda solucion!!! de nuevo muchas gracias… este ha sido muy claro………. me ha solucionado un problema de mi tesis (q la estoy acabando) 🙂

  12. Miren… yo use el evento CellValueChanged una vez k cambiaba el valor el chekbox asi todo lo demas …. calculos etc.. pero antes de salir de este evento es necesario dar un AcceptChanges sobre el source para que los cambios junto con el chekbox se reflejen sean aceptados.

  13. esta es otra pequeña implementacion:

    if (e.ColumnIndex == dgvListado.Columns[“btnselected”].Index)
    {
    DataGridViewCheckBoxCell check = (DataGridViewCheckBoxCell)dgvListado.Rows[e.RowIndex].Cells[“btnselected”];
    check.Value = ( check.Value == null || check.Value.Equals(false) ) ? true : false;
    }

  14. EXCELENTE POST…!! FELICIDADES.. QUE BUENO QUE HAY GENTE CON BUEN CORAZON QUE NOS AYUDA A NOSOTROS.. JUESTO LO QUE ESTABA NECESITANDO.. SI FUNCIONA..!! LO RECOMIENDO

  15. Buen articulo. Estaba buscando por todos los eventos del datagriview y no daba con resolver este problema de checkbox hasta que encontre esta pagina y pude por fin resolverlo.

    Saludos.

  16. Excelente solucion para finalizar el modo “Edicion” en el que se encuentra un check en una fila cuando no cambias el foco y quieres procesar los datos de todas sus selecciones incluyendo esa.

    Gracias por el aporte

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *