jueves, 15 de abril de 2010

C# - [DataGridView] – Uso del CheckBox - DataGridViewCheckBoxColumn

 

Introducción

El articulo intentara mostrar las algunas forma en que se puede utilizar el checkbox en un control DataGridView.

Detectar el cambio en la selección

Para realizar la tarea se hará uso de dos eventos que pueden ser igual de útiles, el CellValueChange y el CellContentClick

De forma estándar el CellValueChange, se deparará a seleccionar el check de la celda y quitar el foco de la misma, saliendo del modo de edición.

Pero este no ejecuta la acción en el mismo instante en que se origina, sino que hay que salir de la edición de la celda para que el evento ocurra.

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
	//
	// Solo se trabaja ante los cambios en la columan de los checkbox 
	//
	if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion") {
		//
		// Se toma la fila seleccionada
		//
		DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

		//
		// Se selecciona la celda del checkbox
		//
		DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;
              
		//
		// Se valida si esta checkeada
		//
		if (Convert.ToBoolean(cellSelecion.Value)) {

                  string mensaje = string.Format("Evento CellValueChanged.\n\nSe ha seccionado, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'", 
                                                      row.Cells["Descripcion"].Value, 
                                                      row.Cells["PrecioUnitario"].Value, 
                                                      row.Cells["UnidadMedida"].Value);

			MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

		}

	}

}

Con respecto al CellContentClick, que si ejecuta la acción en el mismo momento en que el usuario marca, o desmarca, el checkbox, pero me encontré que solo devolvía null en la propiedad Value de la celda.

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    //
    // Detecta si se ha seleccionado el header de la grilla
    //
    if (e.RowIndex == -1)
        return;

    if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion")
    {

        //
        // Se toma la fila seleccionada
        //
        DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

        //
        // Se selecciona la celda del checkbox
        //
        DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;


        if (Convert.ToBoolean(cellSelecion.Value))
        {

            string mensaje = string.Format("Evento CellContentClick.\n\nSe ha seccionado, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'",
                                                row.Cells["Descripcion"].Value,
                                                row.Cells["PrecioUnitario"].Value,
                                                row.Cells["UnidadMedida"].Value);

            MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

        }
        else
        {
            string mensaje = string.Format("Evento CellContentClick.\n\nSe ha quitado la seleccion, \nDescripcion: '{0}', \nPrecio Unitario: '{1}', \nMedida: '{2}'",
                                                row.Cells["Descripcion"].Value,
                                                row.Cells["PrecioUnitario"].Value,
                                                row.Cells["UnidadMedida"].Value);

            MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

        }
    }
}

También se ha intentado hacer uso del evento EditingControlShowing, el cual permitiría detectar la selección en el mismo momento que el usuario realiza la acción, pero esto no fue posible ya que este tipo de columna no provoca el evento necesario para tomar el control CheckBox y asignar el evento SelectedIndexChanged.

Ante este problema con los eventos, y notar que ninguno responde como debería, se encontró un método que resolvió todos los problemas de un solo golpe, se trata del CommitEdit

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty)
    {
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}

En el evento CurrentCellDirtyStateChanged, se detecta si la grilla esta con algún cambio pendiente, y en caso de estarlo se hace un Commit del mismo para reflejar el valor en los eventos que lo usaran. Esto arregla los dos problemas detectados anteriormente:

- se lanza el evento CellValueChanged, sin tener que quitar el foco de la celda

- ya no se recibe el null en el Value de la celda, en el evento CellContentClick

[C#]
[VB.NET]

Aplicar formato a la selección

Teniendo en cuenta lo contado en la sección anterior, aplicar un formato a la fila seleccionada no debería ser un misterio.

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    //
    // Detecta si se ha seleccionado el header de la grilla
    //
    if (e.RowIndex == -1)
        return;

    if (dataGridView1.Columns[e.ColumnIndex].Name == "Seleccion")
    {

        //
        // Se toma la fila seleccionada
        //
        DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

        //
        // Se selecciona la celda del checkbox
        //
        DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;

        if (Convert.ToBoolean(cellSelecion.Value))
            row.DefaultCellStyle.BackColor = Color.Green;    
        else
            row.DefaultCellStyle.BackColor = Color.White; 

    }
}

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.IsCurrentCellDirty)
    {
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}

Simplemente ante la detección de la selección del usuario se cambia el color de la fila usando el DefaultCellStyle.BackColor.

[C#]
[VB.NET]

80 comentarios:

  1. Gracias por el ejemplo y la aclaracion .
    Muchas Gracias

    ResponderEliminar
  2. Excelente aporte, estaba buscando como validad que la columna de ese tipo estuviera marcada y no hallaba la forma, muchas gracias, excelente aporte :D

    ResponderEliminar
  3. Muchas gracias, me estaba volviendo loco con el tema.

    ResponderEliminar
  4. Muy buena la informacion, pero queria molestarte con una consulta, en el ejemplo que muestras en la columna del checkbox en la grilla no esta enlazada a ningun origen de datos.
    YO hago algo igual al ejemplo solo que la columna del checkbox, esta enlazada a una columna del datatable del datasource de la grilla. Y cuando quito el check, elvalor de la celda esta en nulo,pero cuando pongo el check funciona bien.
    Ojala puedas darle una revizada y ayudarme a corregir el error

    ResponderEliminar
  5. hola Fernando S

    has validado las propiedades FalseValue y TrueValue de la columna checkbox del DataGridView

    Valida si la propiedad en FalseValue no tiene un valor nulo por defecto


    saludos

    ResponderEliminar
  6. MessageBox.Show(mensaje, "", MessageBoxButtons.OK, MessageBoxIcon.Information);

    me muestra dos veces el menseje xq ??

    ResponderEliminar
  7. hola que tal amigo mi duda es la siguiente, como puedo controlar por codigo si es que se activo o no un checkbox este se encuentra en una columna del datagridview solo tengo una columna como checkbox las demas estan normalmente como cajas de texto.. ahora el problema es como controlar que active una celda especifica que contiene el ckeckbox es decir desde otro datagridview selecciono un campo especifico y a traves de este lleno con varias opciones el otro datagridview que es el que contiene un campo con un checkbox y en el cual tengo varios registros ahora el problema es que este otro datagridview que tiene el checkbox solo llena datos cuando en el anterior se eligio un dato en especifico pero me topo con el problema de que si elijo uno de estos datos devueltos por el dgv que tiene el checkbox no se como controlar cuando en este se hizo click es decir toma el estado de checked y cuando se desactiva... por codigo como hago esto ya que de este estado depende que se llene otro dgv con otros datos....ojala me entiendan jeje.... es de urgen plissss....

    ResponderEliminar
  8. hola alguien me puede decir por que al ejecutar este codigo brindado cuando lo uso en mi proyecto obviamente con los cambios respectivos me sale este mensaje de error: No se puede reconocer la cadena como un tipo booleano valido. Esto se genera en esta linea de codigo : if(Convert.ToBoolean(cellSelecion.Value))

    no se por que genera este error cuando utilizo en mi proyecto, pues miro en tus ejemplos que se ejecuta sin problema.... porfa a que se debe este error/....???

    ResponderEliminar
  9. hola Edgar Pc Clinic

    bien el erroe puede deberse a que estes seleccionado incorrectamente la celda

    lo que podria sugerrir es que pongas un breakpoint en esa linea y al deterse el codigo pases el mouse por sobre el Value, de esta forma podrias ver que valor contiene y asi saber si este puede o no ser castreado a bool

    recuerda validar si seelccionas correctamente al celda en el evento que sea de la columan del check y no de otra

    saludos

    ResponderEliminar
  10. hola leandro

    tengo un datagridview con datos por fecha ( coje la tabla de datos de sql server) lo que quiero saber es como puedo hacer que desde dos textbox uno se llama "desde" y el otro "hasta" y mediante un boton que al pursarlo me llame la fecha que yo le solicite (desde - hasta. si me puede enviar un ejemplo o algo te lo agradeceria

    ResponderEliminar
  11. hola Joel

    sino entendi mal estos Textbox contendran valores de fechas que usaras de filtro en la consulta que carga el grid

    si es asi revisa este articulo

    [ADO.NET] Filtrar rango de fechas

    saludos

    ResponderEliminar
  12. hola leandro

    en esta ocacion me gustaria saber como yo puedo eliminar un dato de un datagriview es decir que cuando yo seleccione la fila y le de al boton elminar me la elimine pero que ese dato que yo elimine tambien me elimine de la tabla de sql

    ResponderEliminar
  13. hola Joel

    en realidad esto varia dependiendo de como estes implementando las operacioens contra la db

    podrias suar el evento click del boton y alli tomar la informacion del CurrentRow para asi tomar la celda que contenga el id de la entidad que queire eliminar y creas el command que eejcute el DELETE de sql


    saludos

    ResponderEliminar
  14. Buenos dias Leandro, Mira tengo una colsulta , yo tengo un datagridview con chekbox, al momento de que seleccionen reviso si un valor de esa fila cumple con un requisito, si no lo cumple , necesito desseleccionar el chekbgox y levantar un mensage con un messagebox. el problema que tengo que darle value 0 al checkbox, no me desselecciona el valor de forma inmediata si no al momento de perder el foco.

    saludos

    ResponderEliminar
  15. hola ciber_punx

    es que seguramente este en edicion la celda

    que pasa si usas

    DataGridView.EndEdit()

    con esto terminas la edicion y confirmas el valor de la celda

    saludos

    ResponderEliminar
  16. Muchisimas gracias por el ejemplo, funciono perfecto.

    ResponderEliminar
  17. Buenos días Leandro, implemente el código, me funciona perfecto. Pero tengo una consulta...
    Yo uso la columna tipo checkbox para permitir o no permitir editar una celda de la fila seleccionada (cuando doy check row.Cells(i).ReadOnly = False y viceversa), esto lo hago para saber si el usuario hace cambios del valor original antes de grabar en la BD. Pero que pasa si el usuario pone check, le permite editar, luego desmarca el check ya no podría saber si hizo cambios o no en la celda (con el check valido si se hicieron cambios ya que no es solo una celda sino varias). Ahora una idea mia fue en el evento CellValueChanged validar si hace cambios en esa(s) celda(s) entonces la celda del check se vuelve de solo lectura, pero si el usuario vuelve a poner el valor original como hago para que se desmarque el check?
    Por ejemplo:
    el valor que trae del select es 20 solo lectura, se da click en el check le permite editar, pone 23 el check ya no se puede quitar, pero si vuelvo a poner 20 entonces se desmarca el check.
    Espero haberme dejado entender, y me puedas ayudar en como puedo lograr este efecto, gracias de antemano.

    ResponderEliminar
  18. hola Anderssone

    veo dificil que puedas implementar esto como lo planteas porque justamente nom conservas un historico de cambios y valores originales para poder vlidar y decidir el estado del check

    quizas se podrias lograr si vinculas el datagridview a un datatable y de este usas el

    DataTable.GetChanges (Método)

    con este metodo podrias obtener el estado de las filas que cambiaron, el grid impacta contra este control los cambios


    saludos

    ResponderEliminar
  19. Gracias por la sugerencia, trataré de implementar el código, luego te cuento como me fue...

    ResponderEliminar
  20. Mil gracias, estuve tratando dos horas de arreglar el problema, y con unas simples lineas me ahorraste como 10 horas mas.

    ResponderEliminar
  21. Tuve un problema con checkboxcolumns
    Cuando el checkbox de una fila estaba en chequeado y los dechequeaba obteniar un valor DBNull que no podia ser casteado a Boolean. Lo que hice fue utilizar la funcion IsDBNull. Si el valor era DBNull le asigno al checkboxcell.value =false. Me funciona Pero me pregunto si esta correcto lo que hice, es decir existe alguna otra forma mas logica.

    Y Como siempre Gracias a los grandes aportes

    ResponderEliminar
  22. Pues a mi se me ocurrio una idea similar Anderssone, entoces pence que para poder comparar si el usuario podia el mismo valor lo que tenia que hacer es guardar el valor original de la bd en una variable (datatable o array) Para despues comparar el valor en el mismo indice de fila con el datagridview, en caso que coincidiera el valor con el original desmarcar el check.Bueno es solo una idea

    ResponderEliminar
  23. hola escapulario18

    es raro el problema, pero sera quizas que los datos los cargas de los registros de uan tabla en tu db

    porque de ser asi quizas el problema este en que el campo de la tabla permite nulos, y esto lo carga asi en el grid

    podrias hacer que se campo del tipo bit no permita nulos y le pones un valor por defecto, quizas el false sea por defecto

    dee sta forma al vincularse al grid siempre tomara un valor

    saludos

    ResponderEliminar
  24. Hola Leandro, muy buena info, pero tengo un problemita. Tengo un DataGridView, en el cual agregue manualmente una columna con el checkbox y otra 13 columnas para la cantidad de datos que me traigo de la base. Primer problema que me surge es que agregando manualmente las columnas, la info traida de la base (con un dataset) no me la muestra. Y por otro lado no me esta tomando la seleccion tal como dice tu ejemplo. Selecciono el check pero no hace nada. Te agradezco si me podes dar una mano.

    ResponderEliminar
  25. hola Sherman Wall

    cuando no muestra los registros un erro muy comun es no pones el

    GridView1.DataSource = dt
    GridView1.DataBind()

    sino pones el DataBind() no se cargara el control

    con respecto a los checks recuerda que la carga del gris si lo ahces en el Page_Load debes ponerlo dentro del

    if(!IsPoctBack){
    //aqui cargas el grid
    }

    saludos

    ResponderEliminar
  26. hola que tal leandro
    me gustaria sanes como es que agregan el chek box al datagrid segun el numero de reglones que inserte de mi datatable ya que no tneog asociado ninguna columna que contenga checkbox esta en alguna de las propiedades de data grid??

    ResponderEliminar
  27. hola Mario Alberto

    para agregar check es una columan especial de nombre

    DataGridViewCheckBoxColumn

    cuando defines las columnas en tiempo de diseño puede seelccionar este tipo de columna
    o sea aqui imagen

    es en le Type donde seleccionas el tipo

    saludos

    ResponderEliminar
  28. excelente muchas gracias ya lo he agregado

    ResponderEliminar
  29. hola leandro ya eh podido agregar valores de un datagrid a otro gracias a los ejemplo que muestras pero me surge un problema muy raro bueno para empezar solo puedo agregar si se selelcciona la columna donde esta el check pero ese es presisamente lo extrano que si le palomea(Lo cual es correcto) o solo la selecciona le envia informacion exite algo para validar que solamente lo que este palomeado se envie al otro datagrid muestro el codigo que implemente

    private void GenExcDgvDespInfo_CellClick(object sender, DataGridViewCellEventArgs e)
    {
    //MuestraDatosProducto2(e.RowIndex);
    /*CheckBox myCheckBox = (CheckBox)row.FindControl("CheckBox1");
    myCheckBox.Checked = true;*/
    if (GenExcDgvDespInfo.Columns[e.ColumnIndex].Name == "Seleccion")
    {
    DataGridViewRow row = GenExcDgvDespInfo.Rows[e.RowIndex];
    DataGridViewCheckBoxCell cellSelecion = row.Cells["Seleccion"] as DataGridViewCheckBoxCell;
    cellSelecion.Value = true;
    if (Convert.ToBoolean(cellSelecion.Value))
    {
    String ope = (row.Cells[1].Value).ToString();
    GenExcDgvSalTras.Rows.Add(ope);
    }
    else
    {
    cellSelecion.Value = false;
    }
    }
    }

    ResponderEliminar
  30. hola Mario Alberto

    imagino que por pelomeado seginifica que este marcado

    para pasar a otro grid podrias implementar

    [DataGridView] – Pasar Registros entre Grillas

    saludos

    ResponderEliminar
  31. Hola Leandro, muy util el codigo, mi pregunta seria como haria para manipular(eliminar,actualizar,etc) varias filas(row) que tienen el checkbox seleccionado,mediante una columna "Id"que se muestra en el grid(la cual ya tengo), lei uno de tus comentarios que decia que usando el evento click de un boton y el CurrentRow de la fila seleccionada, pero de esta forma solo me toma el ultimo registro seleccionado, no importa si seleccione mas de uno, mi pregunta seria como haria,para obtener todos los "IDs" seleccionados y trabajar con estos, (seria enviarlos a un array o algo parecido?) gracias.

    ResponderEliminar
  32. Hola señor Leandro.
    Tengo un problema en Visual Studio con ese mismo tema. Tengo una Gridcontrol. Consta de 4 columnas
    Nombre
    Optimo
    Dañado
    Estado
    Las columnas Optimo y Dañado tienen celdas tipo CheckBox.
    Lo que quiero es que si se chequea una celda en la culumna "Optimo" en la columna "Estado" de esa misma celda me aparezca como texto "Optimo".
    De lo contrario seria que si chequeo una celda en la columna "Dañado", en la columna "Estado", aparezca en texto "Dañado".
    Espero me pueda ayudar. Mil gracias. Este es mi correo karolfigueroa@misena.edu.co

    ResponderEliminar
  33. hola Karolfigueroa

    pero es lo que se explcia en el articulo, defines el evento CellContentClick
    y alli tomar la fila que lanza la accion para asignar el valor en una de sus celdas

    si detectas la row que lanza el check podrias asignar usando

    row.Cells["Estado"].Value = "Optimo";

    saludos

    ResponderEliminar
  34. Hola Leandro
    Estoy validando datos con un checkbox en un datagridview y cuando pongo el checkbox en true con el mouse con la validación lo quiero mandar a false. he intentado mandando value=false y value=0 pero no se desactiva el checkbox... si me puedes echar la mano te agradecería gracias

    ResponderEliminar
  35. hola ckarlos

    si tienes un checkbox dentro del grid con asignar value no funciona
    debes usar el FindControl() en la row con la cual estas trabajando, seleccionar el check y definir en este el valor Checked

    pero debes hacerlo sobre el control checkbox directo, porque seguro sea un ItemTemplate lo que estas usando

    saludos

    ResponderEliminar
  36. Hola Leandro buenas noches, me parecen muy buenas tus aportaciones, mira tengo un problema que no he solucionado , es sobre un GridView con la propiedad de paginado (10 reg, por pagina) y este tiene una columna con un checkbox la cual la agrue por medio de un Template Field, me detecta los registros de la primera pagina, pero cuado hago cambio de pagina, me quita la selecion de los checkbox, he tratado de agregarlo a una lista con n indice de acuerdo al row seleccionado, pero quiero guaradr los datos los demas datos que tiene el grid view a un datatable, me guarad los datos, pero al hacer le cambio de pagina del gridview me borra el contenido del datatable. Y mi objetivo es guardar en datable el las row que esten selleccionadas, con el fin de continuar usadolos en un siguiente proceso, podrias orientarme, te lo agradeceria..
    GRacias

    ResponderEliminar
  37. hola Angie

    pero es una desarrollo web o desktp el que estas realizando ?
    lo pregunto porque este articulo en que consulta es sobre el datagridview o sea desktop, peor mencioans un gridview que es web

    si quieres conserver los check podrias usar

    [GridView] Mantener checkbox durante la paginación

    saludos

    ResponderEliminar
  38. Del ejemplo que enviaste no tendras algo parecido en asp con vb.net. Si lo tuvieras te lo agradeceria me lo pudieras cmpartir--graxs

    ResponderEliminar
  39. hola Angie

    la verdad no lo traduje a vb.net pero podrias tomar el ejemplo de base he ir convirtiendo a medida que lo implementas usando tool como ser

    http://converter.telerik.com/

    saludos

    ResponderEliminar
  40. Hola Leandro!
    Como estás? Estoy tratando de poner en práctica parte del código que publicaste. Mi idea es, cargo clientes en un Combo, al seleccionar algun cliente, me muestra en la DG las facturas pendientes. A la DG le agrego un Check por Fila, y permito ir seleccionando las facturas a liquidar. La idea es que vaya sumando los valores. El único tema que estoy teniendo que al cargar el Combo, se selecciona el primer cliente, lo cual no me molesta y está bien, pero este, a su vez, tiene una factura sola. Ahora... Si marco o no esa factura, siempre me devuelve True(1) al valor del Check. Si selecciono otro cliente, con más facturas. Anda perfecto. Si despues vuelvo al primer cliente, anda como debe. Se entiende el problema? Es como que no valida el valor del check hasta despues de recargar el DG. Creo al menos. Desde ya, te agradezco cualquier comentario! Saludos

    ResponderEliminar
  41. hola Bubu

    y si al comienzo no se seleccione ningun cliente, o sea pones un item adicional en el combo para indicar la no seleccion del cliente

    ComboBox - DropDownList – Opción “Todos”

    con eso evitarias el problema que se presenta con ese primr cliente seleccionado

    saludos

    ResponderEliminar
  42. Gracias Leandro!
    Si bien el tema de que no anduviese "en la primera carga" era debido a un problema de código, por decirlo de alguna manera (Estaba haciendo referencia a otra columna del DG, perdón por las molestias!) me interesó mucho el artículo que me linkeas.
    Muchas gracias por la predisposición, saludos!

    ResponderEliminar
  43. una pregunta leandro, lo que pasa es que en mi aplicación tengo un datagridview que al momento de seleccionar una fila, los valores de esta se cargan en una serie de texboxs , pero cuando yo selecciono una columna me marcar error,¿ como puedo evitar la selección de columnas?
    ya cambie el valor de la propiedad selectionmode por el de fullrowselect para evitar la seleccion de celdas, pero no puedo evitar la selección de columnas...
    disculpa la molestia.
    Nota: Estoy usando visual studio 2010....y el lenguaje visual basic.net....

    ResponderEliminar
  44. hola Manuel

    imagino la respuesta del foro

    http://social.msdn.microsoft.com/Forums/es-ES/vbes/thread/e65d3cdd-0cc5-41df-940b-dced6d0e387f

    responde la pregunta

    saludos

    ResponderEliminar
  45. Muchas Gracias Leandro por contestar y claro soy el mismo Manuel que hizo la pregunta en el foro. Con tus respuestas pude resolver el problema y disculpa la molestia.
    Gracias por compartir tu valioso tiempo y conocimiento.....

    ResponderEliminar
  46. ojala me puedas ayudar tengo una grilla con paginacion enumerada ..habilitada...etc quiero que al cambiar de pagina me muestre un mensaje de confirm..gracias =!!

    ResponderEliminar
  47. hola EsculpiendoElAlma

    ok tiene un datagridview y por fuera un combo que implementa la paginacion

    podrias usar el evento que permita detectar el cambio de seleccion, aunque no creo que ninguno permita revertir esta accion

    se podria usar el SelectedValueChanged, o SelectedIndexChanged, pero despues de mostrar el mensaje aplciar ala opcion que el usuario seleccion, no mencionas si se podra anular

    saludos

    ResponderEliminar
  48. Hola, hago una pregunta, como hacer para obtener en un arreglo cuales fueron las filas seleccionadas del datagridview con el chekbox

    ResponderEliminar
  49. hola Samuel

    podrias usar linq

    List<string> lista = DataGridView1.Rows.Cast<DataGridViewRow>() .Where(x=> Convert.ToBoolean(x.Cells["nombrecolcheck"].Value)) .Select(x=> Convert.ToString(x.Cells["nombrecolID"].Value)).ToList()

    saludos

    ResponderEliminar
  50. Hola que tal, me ha sido muy util tu post, pero en mi aplicacion que estoy desarrollando igual tengo el datagrid con una columna donde seleccionan los checkboxes, pero aqui requiero que solo puedan seleccionar 2 checkbox en esa columna del datagrid y que los demas checkboxes se deshabiliten, algo asi como un .enable = false, ojala me puedas ayudar. el codigo de esa parte es el siguiente(igual al tuyo):

    if (dgServicio.Columns[e.ColumnIndex].Name == "checkColumn")
    {
    // Se toma la fila seleccionada
    DataGridViewRow row = dgServicio.Rows[e.RowIndex];
    // Seleciona la celda del checkbox
    DataGridViewCheckBoxCell select = row.Cells["checkColumn"] as DataGridViewCheckBoxCell;
    // Se valida
    if (Convert.ToBoolean(select.Value))
    {
    selectOne = (decimal)dgServicio.CurrentRow.Cells["ID"].Value;
    row.DefaultCellStyle.BackColor = Color.LightGreen;
    }

    else { selectOne = 0; row.DefaultCellStyle.BackColor = Color.White; }
    }

    Gracias, excelente blog.

    ResponderEliminar
  51. hola David

    eso de enabled lo veo complicado

    yo dejaria que seleccione lo que quiera sin limitarlo y despues lo validas, si selecciono mas de dos checkbox se lo informas y no continuas con el codigo

    pero lo aplicas como validacion del negocio y no como restriccion a nivel del control visual

    el tema es que para implementar lo que planteas deberias poner en readonly las celdas de los checkbox, o quizas podrias marcar dos y poner en readonly la columna completa

    saludos

    ResponderEliminar
  52. hola Leandro disculpa pero como puedo validar si un checkbox esta seleccionado en una columna en un gridview.

    ResponderEliminar
  53. hola Luz

    la idea es obtener las filas donde los checkbo estan seleccionados ? o solo validar al recoorer las rows si esta marcado

    porque saber el valor es simplemente consultar la propiedad Value, si sabes la row harias

    if(Convert.ToBoolean(row.Cells["nombrecolcheckbox"].Value)){
    //aqui codigo
    }

    con eso evaluas si la celda del checkbox esta marcada



    saludos

    ResponderEliminar
  54. Leandro buenos dias:

    Fantastica tu explicacion, mi pregunta es, stoy trabajando con un Gridview en asp.net ahi tengo 2 checkbox pero requiero que solo se seleccione uno "aceptar" o "rechazar" y dado eso aplicar ese status a una celda, puedes ayudarme con eso.

    Saludos y gracias.

    ResponderEliminar
  55. hola Eduard

    la unica forma que se me ocurre es por medio de jquery, o sea con codigo del lado del cliente

    http://social.msdn.microsoft.com/Forums/es-ES/14c21cfc-f176-45f2-a176-065ae0979b80/limitar-seleccin-checkbox-en-gridview

    saludos

    ResponderEliminar
  56. muy buen aporte!!! sirvió de mucho, tengo una duda, como haría para guardar en un arreglo los id de cada fila, dependiendo si activo el check o no; porque desearía utilizar los id para otra consulta. gracias de antemano

    ResponderEliminar
  57. hola Alexander

    podrias usar algo como ser

    List list = new List();

    foreach(GridViewRow row in GridView1.Rows){

    CheckBox check = row.FindControl("chkSeleccion") as CheckBox;

    if(check.Checked){

    int id = Convert.ToInt32(row.DataKeys[row.Rowindex].Value);
    list.Add(id);

    }

    }

    saludos

    ResponderEliminar
  58. Excelente articulo Leandro, felicitaciones!!!
    Me sirvio de mucho y es algo que se usa mucho en los desarrollos.

    ResponderEliminar
  59. Hola Leandro, una consulta estoy utilizando un Datagrid pero el problema que tengo es que cualquier evento que utilizo veo que dar clic a un campo Checkbox entra 2 veces al mismo evento como puedo evitar esto??? es decir si utlizo el evento CellContentClick o CellClick o cualquier otro evento entra 2 veces. De antemano te agradezco que te tomes el tiempo de leer mi problema Saludos desde Mexico!

    ResponderEliminar
  60. hola Leandro, disculpa que haga esta pregunta aquí pero no encontré un tema en el que estés involucrado en el mismo... mi pregunta es:

    hay alguna manera de poner textos a las filas de un gridview??

    a las columnas ya me sale, pero a las filas no, quiero algo más o menos así:


    ---------------- TÍTULO 1, TÍTULO 2

    TÍTULO 1

    TÍTULO 2



    de antemano, muchas gracias!

    Aarón

    ResponderEliminar
  61. hola Aaron

    de forma directa desde el propio control grid no se puede lograr lo que planteas

    quizas podrias hacerlo aplicando estilos

    GridView : Freezing First Columns and Freezing Column's Headers

    saludos

    ResponderEliminar
  62. Leandro,

    Encontré tu blog y quería hacerte una consulta. Tengo el siguiente código con un datagridview con un checkbox

    DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

    //selecciono la fila de checkbox
    DataGridViewCheckBoxCell cellseleccion = row.Cells[7] as DataGridViewCheckBoxCell;
    bool selec = Convert.ToBoolean(cellseleccion.Value);

    if (selec)
    {
    if (textBoxCliePaga.Text == "")
    {
    MessageBox.Show("No hay ingresado monto a pagar, complete el campo Cliente Paga", "Facturacion",
    MessageBoxButtons.OK, MessageBoxIcon.Warning);


    }

    En la parte que aparece el messagebox quisiera que se destilde el checkbox como debería de hacerlo. Probé con Value = false pero sigue seleccionado.

    Esto es en c#

    Desde ya muchas gracias,

    Saludos atte.

    ResponderEliminar
  63. Hola Leandro. Te quería preguntar como se podría seleccionar varios DataGridViewCheckBoxColumn del datagriview en Vs. Net.?
    Ya que cuando tildo uno y luego intento tildar otro, se me destilda el anterior.
    Gracias por tu ayuda.

    Saludos, Matías.

    ResponderEliminar
  64. Hola Leandro, una consulta,tengo un datagridview con datos obtenidos de mi db, lo que busco es poder agregar una columna en la pueda ingresar por fila una "cantidad" por teclado y asi enviar todo a mi db.

    De Antemano Muchas Gracias!!...

    ResponderEliminar
  65. hola Cheyo

    si defines las columnas en tiempo de diseño podrias agregar una adicional para cargar estos datos, sabes como definir las columnas en diseño y asignar el PropertyName ?

    tambien podrias definir la columna en el origen de datos, no se si usas un datatable o una lista, pero si defines en esta esa columna o propiedad se vera cuando lo asignes al datasource del grid

    saludos

    ResponderEliminar
  66. hola Leandro
    perdon por la demora en dar las Gracias...aplique la primer opcion.

    ResponderEliminar
  67. Hola Leandro, tengo un problema con los check de la grilla porque no cambian de valor al chequearlos.
    El tema es que si yo le asigno la PropertyName, me carga el valor, pero si le hago click no cambia. queda como readonly y si le cambio en tiempo de ejecución (después de la carga de la grilla) a ReadOnly=false; me da el error "Una columna DataGridView enlazada a un archivo de sólo lectura debe tener ReadOnly establecido en True."
    Como hago que el datatable sea readwrite? o que me quede el checkbox cargado y que lo pueda modificar. (ojo no quiero que se modifique en la base ni nada, solo que me cargue el valor al inicio y poder modificarlos). Luego tengo un método que recorre la grilla y guarda los cambios en la BD.

    Desde ya muchas gracias

    Ariel D'Alfeo

    ResponderEliminar
    Respuestas
    1. hola

      entiendo que defines las columnas en tiempo de diseño, entocnes esa columna del tipo checkbox no deberias definirle ningun PropertyName
      el resto de las columnas si deberian mapearse a los campos del datatable, pero el de check no haria falta

      saludos

      Eliminar
  68. buenas leandro lo que quisera hacer es tengo 2 datagridvew cargados con 2 tablas iguales ..
    1.- como hago para colocarle el check en el header?
    2.- cuando hago seleccion el header que se seleccionen todos los disponibles en el datagrid
    3.- que cuando tenga marcados los disponibles y accione el control buton envie toda la data al otro datagrid es posible?

    ResponderEliminar
  69. Leandro, necesito Codigo Ejemplo Por Favor
    gracias

    ResponderEliminar
    Respuestas
    1. con esto tienes adaptalo a tu datagrid

      Private Sub detalle_cliente_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles detalle_cliente.CellValueChanged
      If e.RowIndex = -1 Then
      Return
      End If

      End Sub

      Private Sub detalle_cliente_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles detalle_cliente.CurrentCellDirtyStateChanged
      If detalle_cliente.IsCurrentCellDirty Then
      detalle_cliente.CommitEdit(DataGridViewDataErrorContexts.Commit)
      End If
      End Sub
      Private Function EstadoCheck(ByVal filaposicion As Integer) As Boolean
      Return Me.detalle_cliente.Rows(filaposicion).Cells(0).Value
      End Function

      Eliminar
  70. Yo tengo una gran duda Leandro tuttini.
    Necesito hacer una suma, pero necesito que la suma se haga al momento de cambiar el valor de la celda
    Me puedes ayudar??

    ResponderEliminar
  71. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  72. hola Leandro
    buena aportación, me queda duda, si quisiera traer la información completa de cada uno de los renglones como se codificaria en C#.... a y nuevamente gracias por la aportación.

    ResponderEliminar
    Respuestas
    1. hola Leandro
      buena aportación, me queda duda, si quisiera traer la información completa de cada uno de los renglones como se codificaria en C# a y nuevamente gracias por la aportación.

      Eliminar
  73. Para los que quiere cambiar un LABEL al marcar el checkbox y solo cambia cuando hacen click en otra celda y no al "Instante", la solución en Vb.net es como dice Leandro:
    Agregar en "dataGridView1_CurrentCellDirtyStateChanged" el If y walá!


    Private Sub dataGridView1_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As EventArgs)
    If dataGridView1.IsCurrentCellDirty Then
    dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
    End If

    End Sub


    Pd: Leantro Te amo! Sos el mejor! Hace dos horas que estoy con este problema

    PD2: https://www.carlosag.net/tools/codetranslator/ Esa pagina tradujo a la perfección el lenguaje!


    Pd3: www.yosoycomputacion.com

    ResponderEliminar
  74. Hola ¿Hay un ejemplo igual pero en csharp subido?

    ResponderEliminar
  75. Tengo un grid relacionado a una base de datos, la columna selección es de tipo BIT y es la misma columna que en el grid es checkbox, pero cuando hago el select en esa columna me pone CEROS o unos en lugar del control chequeado o no... cómo hago para que se mantenga el control? mi código está asi:

    public DataTable ConsultarFlujos()
    {
    DataTable dt = new DataTable();
    try
    {
    MySqlCommand Consulta = conn.Connection.CreateCommand();
    Consulta.CommandText = "Select Seleccion, Id_script as 'ID Script', Nombre_script AS 'Nombre Script' FROM tb_reaseg_scripts WHERE Id_aplicativo = '001'";
    conn.AbrirConexion();
    MySqlDataReader Reader = Consulta.ExecuteReader();
    dt.Load(Reader);

    conn.Connection.Close();
    return dt;
    }
    catch (Exception ex)
    {
    System.Windows.Forms.MessageBox.Show("Error al cargar flujos del aplicativo 001", "Error", System.Windows.Forms.MessageBoxButtons.OK, MessageBoxIcon.Error);
    return dt;
    }
    }

    Gracias de antemano

    ResponderEliminar