miércoles, 20 de enero de 2010

[DataGridView] - Uso del DataGridViewComboBoxColumn

 

Introducción


Este articulo tendrá por objetivo mostrar como trabajar con las columna del tipo ComboBox que se encuentran dentro de una celda del datagridview.

 

1- Definición de las columnas en tiempo de diseño


Un paso importante es la definición de las columnas para ello en este caso explicare como hacerlo en tiempo de diseño y poder así controlar que datos visualizar.

La opción para realizar esta operación se encuentra haciendo click con el botón derecho del mouse en el control DataGridView del formulario, visualizando una lista de ítems como se muestran en la imagen

titulo1-imagen1

Aquí puede seleccionarse dos opciones:

- Agregar nuevas columnas a la grilla por medio de la opción “Add Column …” visualizándose el siguiente cuadro:

titulo1-imagen2

Como se observa en la imagen, puede definirse información rápida del tipo de columna que se quiere representar en la grilla.

- Editar columnas existentes, mediante la opción “Edit Columns…” visualizando un cuadro como el siguiente

titulo1-imagen3

Lo interesante de esto es que uno podrá controlar que visualizar, en que orden, formato, tipo de columna y además todo desde un entorno visual

La idea de estos diálogos es definir rápidamente las columnas mediante la opción de “Add Column…” para luego pasar a la edición mediante “Edit Columns…” y especificar propiedades que son importantes para que todo funcione.

Una de las propiedades importantes es DataPropertyName, esta es fundamental para indicar que campo del origen de datos será asignado a esa columna. Al momento de cargar la grilla el valor de esa propiedad será tomado del origen de datos y asea un DataTable, o List<>, o cualquier otro que sea asignado y se mapeará con la columna usando esta propiedad.

Sino se asigna información a la propiedad DataPropertyName ese campo no cargara datos alguno, lo cual puede ser interesante para campos calculados como veremos en ejemplo mas adelante.

Es importante además que la propiedad AutoGenerateColumns sea establecida en false cuando se definan las columnas en tiempo de diseño, ya que en caso de no hacerlo se añadirá a la grilla las columnas generadas en runtime, lo cual no es deseable en este caso.

 

2 – Asignación de los datos a la columna DataGridViewComboBoxColumn


Empezaremos por cargar la información en un ejemplo simple, en este solo se tendrá un único campo del tipo combobox en el columna del DataGridView.

En este caso se trata de una grilla de producto con sus precios unitarios, además cada producto pertenece a una marca especifica, que podrá seleccionarse entre las disponibles por el sistema.

Los pasos a seguir serán:

- se recuperara la columna que fue definida del tipo combobox a la cual se le asignaran los datos a desplegar, en este caso serán las Marcas disponibles.

- y por ultimo se cargara la grilla con los datos de los Productos.

El formulario que visualizaría será el siguiente:

titulo2-imagen1

La carga de los datos se ha realizado en el evento Load del formulario

private void Form1_Load(object sender, EventArgs e)
{
    //
    // Asigno los datos del combo de marcas
    //
    DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] as DataGridViewComboBoxColumn;

    comboboxColumn.DataSource = ProductosDAL.GetAllMarca();
    comboboxColumn.DisplayMember = "Descripcion";
    comboboxColumn.ValueMember = "IdMarca";

    //
    // bindeo los datos de los productos a la grilla
    //
    dataGridView1.AutoGenerateColumns = false;
    dataGridView1.DataSource = ProductosDAL.GetAllProductos();

}

Es interesante notar que la primer parte se recupera la columna del DataGridView que define el combobox, la cual se programa como si se tratara de un combobox normal de .net, utilizando las propiedades DataSource, a la cual se le asignado el origen de datos con la lista de Marcas, el DisplayMember y ValueMember, para asignar que campo de la lista de Marcas será visible al usuario y cual será el id de cada ítem listado.

El segunda parte carga los datos del DataGridView, tomando todos los producto a mostrar en la grilla.

Además se especifica la propiedad AutoGenerateColumns definiendo que solo las columnas creadas en tiempo de diseño serán las visibles.

A continuación se visualizara los método utilizados para cargar los datos en el DataGridView

public static List<MarcaEntity> GetAllMarca()
{
    string sql = @"SELECT IdMarca
                          ,Descripcion
                      FROM Marcas";

    List<MarcaEntity> list = new List<MarcaEntity>();

    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        OleDbCommand command = new OleDbCommand(sql, conn);

        conn.Open();

        OleDbDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            list.Add(LoadMarca(reader));
        }

        return list;
    }
}

private static MarcaEntity LoadMarca(IDataReader reader)
{
    MarcaEntity marca = new MarcaEntity();

    marca.IdMarca = Convert.ToInt32(reader["IdMarca"]);
    marca.Descripcion = Convert.ToString(reader["Descripcion"]);

    return marca;
}

 

public static List<ProductoEntity> GetAllProductos()
{
    string sql = @"SELECT [IdProducto]
                          ,[IdMarca]
                          ,[Descripcion]
                          ,[PrecioUnitario]
                      FROM Productos";

    List<ProductoEntity> list = new List<ProductoEntity>();

    using (OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
    {

        OleDbCommand command = new OleDbCommand(sql, conn);

        conn.Open();

        OleDbDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            list.Add(LoadProducto(reader));
        }

        return list;
    }


}

private static ProductoEntity LoadProducto(IDataReader reader)
{
    ProductoEntity producto = new ProductoEntity();

    producto.IdProducto = Convert.ToInt32(reader["IdProducto"]);

    producto.IdMarca = Convert.ToInt32(reader["IdMarca"]);
    producto.Descripcion = Convert.ToString(reader["Descripcion"]);

    producto.PrecioUnitario = Convert.ToDecimal(reader["PrecioUnitario"]);

    return producto;
}
     
[C#]
[VB.NET]

 

3 – Realizar una operación al cambiar la selección del combo


En este sección se analizara como poder trabajar con un combobox que ha sido agregado a la grilla.

En este ejemplo se agrego un atributo nuevo al producto, referido a un descuento, según el el valor seleccionado del combo se realizara una operación con el mismo y el valor calculado será presentado en otra celda de la misma fila en donde se visualiza la información del producto.

El formulario ahora tomara la siguiente forma

titulo3-imagen1

Además si se analiza las propiedades de la nueva columna se podrá apreciar que la propiedad DataPropertyName se le ha especificado el nombre del campo de la tabla de productos, y es el mismo nombre de la propiedad en la clase ProductoEntity.

titulo3-imagen2

A diferencia el ejemplo anterior en este solo se agregaron las línea para cargar los ítems de descuento

private void Form1_Load(object sender, EventArgs e)
{
    //
    // Asigno los datos del combo de marcas
    //
    DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] as DataGridViewComboBoxColumn;

    comboboxColumn.DataSource = ProductosDAL.GetAllMarca();
    comboboxColumn.DisplayMember = "Descripcion";
    comboboxColumn.ValueMember = "IdMarca";

    //
    // Asigno los datos del combo de descuentos
    //
    DataGridViewComboBoxColumn dgccomboDescuento = dataGridView1.Columns["Descuento"] as DataGridViewComboBoxColumn;

    dgccomboDescuento.DataSource = ProductosDAL.GetAllDescuentos();
    dgccomboDescuento.DisplayMember = "Descripcion";
    dgccomboDescuento.ValueMember = "IdDescuento";

    //
    // bindeo los datos de los productos a la grilla
    //
    dataGridView1.AutoGenerateColumns = false;
    dataGridView1.DataSource = ProductosDAL.GetAllProductos();

}

Pero lo mas importante es ver como se trabaja con el combo, detectando un cambio en el ítem y realizando el calculo del descuento.

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{

    if (dataGridView1.Columns[e.ColumnIndex].Name == "Descuento")
    {
        //
        // se obtiene el valor seleccionado en el combo
        //
        DataGridViewComboBoxCell combo = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell;

        int idDescuento = Convert.ToInt32(combo.Value);

        //
        // se recupera por el id la info del descuento
        //
        DescuentoEntity descuento = ProductosDAL.GetDescuentosById(idDescuento);

        //
        // se calcula el descuento
        //
        DataGridViewCell cellPrecioUnitario = dataGridView1.Rows[e.RowIndex].Cells["Precio"];
        DataGridViewCell cellPrecioFinal = dataGridView1.Rows[e.RowIndex].Cells["PrecioFinal"];

        decimal valordescontar = (descuento.Porcentaje * Convert.ToDecimal(cellPrecioUnitario.Value)) / 100;

        cellPrecioFinal.Value = Convert.ToDecimal(cellPrecioUnitario.Value) - valordescontar;
    }
}

En este caso se hizo uso del evento CellValueChange, y dentro de este se realizando las operaciones para trabajar con el valor seleccionado del combo.

- Primeramente se valida que siempre se trabaje con la columna que uno quiere operar, en este caso por el nombre se valida que sea la definida para el descuento. Debe recordarse que estos eventos también puede disparase para la edición de otras celdas para las demás columnas. Pero en este caso como el calculo solo interesa hacerlo en la columna de descuento es esta la verificada.

- Como segundo pasos se toma el id del descuento seleccionado en el combo, debe recordarse que al momento de cargar los ítems del combo, fueron los id los que se unieron a la propiedad ValueMember.

- Con el id del descuento se accede a la base de datos para recuperar la entidad del descuento  y con esta el valor del porcentaje que será usado en el calculo

- Por ultimo se recuperas la información de las celdas que restan y se procede a realizar el calculo del porcentaje que será desplegado en la ultima columna de la grilla.

Algo interesante a notar es que esta ultima columna que se hace llamar “Precio Final” no tiene valor alguno en la propiedad DataPropertyName, es por ello que no se carga ningún valor proveniente de la base de datos.

 

[C#]
[VB.NET]

199 comentarios:

  1. Hola Leandro,

    ¿cómo se pueden hacer las operaciones de delete e insert de filas en el datagridview?. He visto que update si que te permite (tengo las propiedades de AllowDelete y AllowInsert en true) pero no me permite hacer nada. Supongo que tienes que controlar la pulsación de alguna tecla. Es que como si usas un databinding a ADO.NET tipado va solito.

    Muchas gracias por anticipado y un saludo.

    ResponderEliminar
  2. hola

    Las operaciones de delete e insert si es que las has habilitado en el datagridview, operan sobre el origen de datos que has establecido.
    Por ejemplo si has usado un dataset cuando tomes de la propeidad DataSource del DataGridView podras consultas que registros se han agregado y cuales borrado, para luego poder operar con ellos

    Por lo general a mi me gusta que sea algo mas online, cuando el usuario realzia una oepracion de delete de un registro en la grilla, directamente impacto esta sobre la db, este tipod e acciones asl veras en otro ejemplos que aplico en el blog, los realcionados con ADO.NET

    saludos

    ResponderEliminar
  3. Hola,

    las propiedades AllowInsert y AllowDelete están habilitadas. El datasource es una consulta LINQ. He probado a hacerlo con un databinding de un dataset tipado y funciona correctamente. Lo que sucede es que me gustaría no usar dataset tipados. ¿Qué datasource usas tu?.

    Muchas gracias.

    Antonio.

    ResponderEliminar
  4. hola

    Estoy algo confundido, dices que usas una consulta Linq, pero luego comentas que te gustaria usar dataset tipados.

    Sera que estas usando Linq to SQL?

    Como habras visto en los ejemplos tiendo a usar clases custom para operar con las entidades, y no soy mucho de la edicion directa en la grilla, prefiero seleccionar un item y editarlo en cuadros de texto, combos y demas controles simples ya que tengo la experiencia que por mas que la edicion sea simple las validaciones y controles no lo son, y la grilla no se presta a validaciones muy complejas ni evento relacionados.

    Por ejemplo cuando tienes combos anidados que seleccionar, es muy complejo lograrlo en el datagridview, por eso recurro a la edicion por fuera.

    Mas alla de eso si uasas dataset tipados, como es que queires hacerlo, estos deberian ser 100% compatibles con al edicion que quieres hacer sobre la grilla, lo que no creo que sea compatible es si usas una consulta linq ademas no recomendaria que se edite sobre el resultado de una consulta a un objeto

    saludos

    ResponderEliminar
  5. hey que onda, mucho gusto, mira me interesa desplegar ciertos elementos en un comboBox en uno de los campos del datagridview, pero no estoy intentando jalar ningun dato de ninguna base de datos a ese combobox simplemente agregarlos y que los muestre pues en forma de dropdown menu o comboBox, ya intente agregar los elementos a la propiedad items de la columna y si me muestra una pestaña pero cuando le doy clic no abre ni despliega nada!!! podrias ayudarme 8(

    ResponderEliminar
  6. hola Jonathan

    la verdad es un poco raro que con la propiedad Items no pudieras realizarlo

    DataGridViewComboBoxColumn.Items (Propiedad)
    http://msdn.microsoft.com/es-es/library/system.windows.forms.datagridviewcomboboxcolumn.items.aspx

    con esta puedes agregar por medio de codigo cada valor mediante e metodo Add() o AddRange()

    habria que analizar el codigo que estas utilizando, pero si has seguido el ejemplo de este articulo veras que si obtienes el DataGridViewComboBoxColumn, a este le puedes asignarlo valores que veras en todos los combos de cada fila

    saludos

    ResponderEliminar
  7. *volvi a quitar la columna y la agregue de nuevo y si me empezo a desplegar los items, tambien puse la opcion readonly como false y ya esta funcionando!!!. Estoy intentando clasificar los items del dropdown ya que manejo unidades de medidas de litros y gramos y me gustaria que al momento de seleccionar una radiobutton me mostrara solo los items liquidos y al seleccionar el 2do radiobutton mostrara solo los gramos.

    ResponderEliminar
  8. Jonathan, que tal

    que bien que has podido solucionar el problema.

    bien por la otra consulta en realidad depende de donde quieres ubicar los radiobutton si es fuera en el formulario, o dentro de la grilla.

    Si es dentro de la grilla la verdad no lo recomendaria, cuando tienes logica anidada la verdad es un tanto complejo el desarrollo, no se lleva muy bien el datagridview con tareas que dependen de otra, mas que nada porque es complicado determinar los eventos de seleccion.

    Lo que yo hago en estos caso cuando la informacion mostrada es dependiente una de otra, simplemetne otorgo al funcionaldiad de edicion por fuera de la grilla, veras en muchos ejemplos que arme que al hacer doble click en una fila los valores de esta se copian a controles por fuera, ya sean textbox, combobox, etc, se edita alli sin problemas, (aunque exista funcionalidad anidada), y por ultimo se actualiza la informacion reflejando el cambio en la grilla

    la verdad es lo mas simple que encontre ante estos casos

    por ahi sino podrias hacer la consulta en los foros de msdn, alguien que haya tenido este mismo planteo podrias darte una solucion algo mas acertada

    saludo

    ResponderEliminar
  9. Leanro muy bueno el ejemplo como todos lo que pones en el blog, solo tengo una consulta, en el ejmplo de descarga veo que el calculo del total lo haces en el evento dataGridView1_CellValueChanged y tambien el mismo codigo lo tienes en el dataGridView1_CellFormatting.
    Es necesario tener el mismo codigo en los dos eventos?? Gracias por su respuesta.
    Nota: Ojala y puedas darte un tiempito y avanzar con el ejemplo de N-tier que lo ando esperando jejeje. Saludos y un buen dia

    ResponderEliminar
  10. leandro una consulta sobre el ejemplo, como podria hacer para que en la grilla salga por default siempre la primera opcion del combo ya seleccionada?.

    Saludos

    ResponderEliminar
  11. hola Fernando,

    Sobre el tema de tener la misma funcionalidad en ambos eventos, basicamente es porque cada uno actua en un momento distinto.

    En el CellFormatting se ejecuta cuando es bindeado el control a los datos, o sea es la inicializacion de la informacion en la grilla.
    En cambio el CellValueChanged es accionado cuando el usuario opera con la grilla, con los datos ya cargados, es un evento a nivel de operacion.

    Por ahi le faltaria un poco de refactor al ejemplo, este procesamiento repetido podrias sacarse a un metodo que sera invocado desde ambos eventos, de esta forma no tendra codigo duplciado.

    Saludos

    ResponderEliminar
  12. Fernando,

    Con respecto a la seleccion de la primera opcion.

    Podrias usar el evento CellFormating, alli tomar la celda que representa el combo y asignarle el SelectedIndex = 0

    Aunque otra tecnica que podrias aplicar, luego de cargar la grilla podrias hacer un foreach por cada Row y tomando la celda del combo especificar el indice por defecto.
    Por supuesto esta ultima la aplicarias luego de asignar el DataSource del control, por eso comentaba que seria despues de la carga de la grilla.

    saludos

    ResponderEliminar
  13. hola, estoy con dos comboBox, en los dos tengo datos cargados de la base de datos, en uno tengo el id del producto y en el otro el nombre del producto, quiero hacer este evento, que cuando seleccione en el primero el id, automaticamente aparesca en el segundo el nombre y viceversa, me podrias decir que evento es en el datagrid, y como se hace, gracias

    ResponderEliminar
  14. hola mijares,

    La verdad no te recomendaria que trabajes de esa forma la grilla, no he tenido muy buena experiencia en el uso del DataGridView cuando se trabjan com combos anidados.

    El problema radica en que no se tiene un buen control de los eventos para poder acceder a la celda una vez lanzado el evento del combo.

    Cuando tienes este tipo de escenarios es aconsejable que armes un mecanismo que permita la seleccion de la fila y la edicion de los item por fuera de la grilla, con combos y textbox comunes, acto seguido al terminar la edicion actualizarias la info

    saludos

    ResponderEliminar
  15. HOLA

    ¿COMO PUEDO HACER PARA QUE MUESTRE EN MI DATAGRIDVIEW SOLO DOS CAMPOS A PARTIR DE UNA CONSULTA?

    SELECT CODIGO,NOMBRE FROM CLIENTES WHERE NOMBRE LIKE '%ANDRES%';

    ResponderEliminar
  16. hola

    Si analizas la seccion "1- Definición de las columnas en tiempo de diseño" de este mismo articulo, veras que alli describo como definir las columnas que mostraras en la grilla

    Mas alla que tu datatable tenga muchos campos, si defines las columnas en la grilla solo estas se mostraran.

    Presta atencion a las propiedades DataPropertyName (define los nombres de los campos de tu origen de datos, en cada columna) y AutoGenerateColumns (usalo en false).

    Puedes descargar el ejemplo de codigo y analizar estas propiedades como son usadas.

    salduos

    ResponderEliminar
  17. como podemos hacer eso mismo pero con los elementos enlazados (Databinding)?

    ResponderEliminar
  18. hola tocayo

    En realidad hasta donde puedo ver no se si es necesario utilizar DataBindings, ya que la union de la columna con tu origen de datos lo logras por medio de la propiedad
    DataPropertyName que defines en la columna del tipo combobox

    Esto une el campo de tu datatable que asignas en el DataSource del control, con el "SelectedValue" del campo definido como combo.

    Nota: puse SelectedValue entre comillas ya que en realidad esto es transparente, no estas asignando a esta propiedad porque no la tienes disponible, se hace de forma automatica segun los datos que aportas y los disponivbles en el combo, esto lo haces mediante la defincion del DataPropertyName.

    saludos

    ResponderEliminar
  19. Primero que nada, Muchas Gracias por el tutorial, es de GRAN AYUDA ;)!!!

    Ahora solo vengo con una duda, yo hago hago similar, así que al calcular mi precio final y colocarlo en la celda del mismo nombre, eso no aparece sino hasta que doy click en ella, habrá alguna manera de hacerlo automático desde que seleccionamos un valor en la celda ComboBox??

    Muchas Gracias de Nuevo y disculpa las molestias ;).

    ResponderEliminar
  20. Hola Tania

    Sino entendi mal la pregunta, te refieres a que el evento CellValueChanged de la celda para detectar la seleccion del combo, solo se produce una vez que se deja la celda, o sea se sale de la edicion.

    Recientemente en un articulo, estuve viendo ese tema, ya que me sucedia lo mismo, solo que con checkbox.

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

    No lo implemente com combobox pero creo que si aplicas el mismo concepto, podria dar resultado.

    Basicamente consiste en implementar esta parte:

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

    realiza las pruebas y cuentame que tal ha salido.

    saludos

    ResponderEliminar
  21. Hola:

    Primero que nada Muchas Gracias por responderme y para no dejarte con la duda, tu ayuda me sirvió de mucho :P y lo encontre en tu blog, pero en el siguiente artículo:http://ltuttini.blogspot.com/2010/03/datagridview-parte-6-combobox-y-evento.html .

    Lo que yo quería es que, con forme seleccionarás la cantidad del producto con el Combobox, se calculará automaticamente por el precio y me mostrará el Precio Final, use los Eventos: private void dgvLista_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) y private void dvgCombo_SelectedIndexChanged(object sender, EventArgs e).

    Tienes un Blog Muy Bueno ;), Gracias de Nuevo ;)!!!

    ResponderEliminar
  22. Hola Maestro , mi pregunta es la sgte:
    tengo un form padre en el cual tengo los datos de un registro en el cual hay un check que me dice el estado activo, al hacer clic en un boton busca me llama a un form modal el cual tiene un gridview con la columna activo como check, el cual tiene toda la lista de registros de la bd el cual deberia actualizarse cada vez q edito ese check en el padre, y hago clic en el boton q yama al modal pero no lo hace, mas cuando realizo la llamada desde el mismo modal si se actualiza el gridview con los checks, que podria ser maestro Leandro, uso vb.net 2005 (asp.net) y sql 2005

    ResponderEliminar
  23. hola Luis

    Disculpa la demora de la respuesta.

    En la explciacion que das hay algo que que no me termina de cerrar, ya que mencionas que tienes problemas para desplegar el popup modal, pero depues sigue comentando que desde este puedes actualizar la info de la gridview, esa parte confunde un poco.

    Algo que no has comentado es como estas implementando este popup, quizas usas los controles de Microsoft Ajax ?

    creo que se necesitaria ver algo del codigo que estas usando, pero ponerlo aqui va a ser algo complicado, mas que nada para repetar la identacion del codigo.

    Lo que recomendaria es que realices esta pregunta en los foros de MSDN

    ASP.NET Foro

    Yo participo activamente en esos foros, y sino soy yo seguro alguien estara dispuesto a dar una mano.
    Alli podras agregar codigo y explciar claramente el problema.

    saludos

    ResponderEliminar
  24. Hola como estas muy bueno tu ejemplo, pero yo no quiere obtener el valor(osea el id) del combo de la columna sino quiero el texto del combo, favor ayudame con esta preguntas, gracias

    ResponderEliminar
  25. hola Anita

    Se me ocurre que podrias al momento de cargar el combo especificar tanto en el DisplayMember, como en el ValueMember, el mismo campo, en el ejemplo podrias ser algo como esto:

    comboboxColumn.DataSource = ProductosDAL.GetAllMarca();
    comboboxColumn.DisplayMember = "Descripcion";
    comboboxColumn.ValueMember = "Descripcion";

    Entonces cuando obtengas el valor de la celda del combo usando el Value tendrias la descripcion.

    En este caso se visualizara lo mismo que se obtendra en la seleccion, porque se ha definido el mismo campo para bindear la info.

    saludos

    ResponderEliminar
  26. Buenas noches Leandro,
    Necesito ingresar datos a una base de datos por medio de un DataGridView, cómo lo puedo realizar?.
    Vendría siendo un formulario de pedidos, el grid tendría una columna tipo combobox donde están los productos, al seleccionar alguno me mostraría el precio, existencia, etc en las otras columnas y otra columna para la cantidad pedida.
    La idea es que a medida que vaya terminando una línea, ésta se guarde en la bd, por ende si la borro o la modifico también lo haga en la bd.
    Me explico bien?
    Gracias de antemano
    Saludos

    ResponderEliminar
  27. hola Conchi

    te comento que arme un ejemeplo en el link

    [N-Tier] – Desarrollo en capas - Ejemplo Facturación – Parte 1

    por ahi te es de utilidad

    Aun no este completamente terminado, ya que falta la edicion de la factura, pero si podrias ver como trabajar con los datos de la grilla para poder insertar los items en la tabla.

    Igualmente esta es una primera aproximacion falta terminarlo, por ejemplo la creacion de cada linea la realizo invocando al metodo que la inserta, pero deberia poder crearse todas sin necesidad de crear un SqlCommand nuevo.

    Pero creo que como primer aproximacion podria usarse para sacar algunas ideas.

    saludos

    ResponderEliminar
  28. Muchísimas gracias Leandro.

    Voy a revisar el código y te comento los resultados.

    Saludos,
    Conchi

    ResponderEliminar
  29. Hola Leandro,

    Estoy utilizando parte del código del ejemplo que me indicaste, pero tengo problemas al insertar, modificar y eliminar datos en la BD.
    Desde el mismo ejemplo me pasa, puedo ver los datos de la BD, en el formulario frmCompra ingreso un nuevo cliente, cargo una supuesta compra y confirmo.
    Si no cierro la aplicación, puedo ver el nuevo cliente en el form frmBuscarCliente, pero una vez que la cierro y vuelvo a entrar ya no se ve. Y el la BD no se actualizó tampoco..

    Que pudiera ser?

    Saludos y gracias de antemano.
    Conchi

    ResponderEliminar
  30. hola Conchi

    Como en el ejmeplo estas usando sql server como db ?
    Si es asi la tienes integrada al VS ?

    Lo pregunto porque recuerda que cuando detiene y vuelves a ejecutar la aplicacion el VS pisa el .mdf que esta en la carpeta bin\Debug
    por eso cuando detiene y vuelve a ejcutar los datos ya no estan

    Para probarlo copia el contenido de bin\Debug a otro sitio y ejecuta directo desde el .exe, veras que ahora si se mentiene la info

    saludos

    ResponderEliminar
  31. Mil gracias Leandro,

    Exactamente eso era lo que me pasaba. Estoy usando SQL Server Express integrado a VB.
    Otra consulta aprovechando la oportunidad.
    Esta bd integrada al vs es ideal para hacer paquetes de distribución de mi aplicación?
    Originalmente había pensado hacer mi aplicación con Mysql, pero luego pensé que sería tediosa la instalación en los clientes, ya que serán muchos y la idea es entregarles el instalador y que ellos mismos lo instalen.

    Gracias nuevamente,
    Conchi

    ResponderEliminar
  32. hola Conchi

    En realidad te va a facilitar la distribucion de tu base de datos, pero no el motor de Sql Server Express.

    Cuando lleves la aplicacion al usuario vas a tener que instalar dos cosas:
    - la aplicacion propiamente dicha, la cual incluira localmente el .mdf

    - el motor de sql server, el que permite que la db se attache dinamicamente

    Y te recomiendo que los mantegas por separado, ya que integrar el motor al intalador no es simple de lograr.

    saludos

    ResponderEliminar
  33. Hola.. Esta muy interesante, haber si me puedes ayudar con esto, tengo una grid, que genera filas automáticas, como le coloco valores por defecto a esas filas? lo intente con el DatapropertyName, pero no paso nada, el problema es q estoy usando eventos como clic que hacen cálculos, si hago clic en filas vacías, me revienta porq los cálculos no los puede hacer con vacio (""), quiero colocarle cero (0) a todas las filas q se generen por si solas..

    Gracias!!

    ResponderEliminar
  34. hola Pierina

    En principio puedo comentarte que la propiedad DatapropertyName, no esta pensada para definir valores por defecto, sino que mapea el nombre de campo del origen de datos, que sera usado para bindeara en esa columna.
    O sea, que campo de tu datatable se cargara alli cuando asignes el DataSource de la grilla.

    Podrias ver si algo como esto ayuda

    Cómo: Especificar valores predeterminados para nuevas filas en el control DataGridView de formularios Windows Forms

    Pero no estoy seguro que lo haga ya que segun veo aplica cuando se crea un registro nuevo programaticamente, no bindeando los datos.

    Lo que si podria funcionar es si usas:

    Cómo: Dar formato a datos en el control DataGridView de formularios Windows Forms

    Revisa donde dice:Para personalizar la presentación de valores de base de datos null

    Creo que esto es lo que podrias solucionar el problema.

    saludos

    ResponderEliminar
  35. Muchass gracias!! el primer articulo funciona perfectamente :D, es apropiado porque hasta que no haga clic sobre la fila no muestra los valores y eso esta bien así! :D, tengo otra consultar, necesito que al escribir en una celda en modo de edición, se me vayan actualizando las otras celdas de la grid, es un efecto como el Change en los textbox, no he encontrado ningún evento que haga esto, solo dos trucos, uno utilizar el KeyPress llamado desde un evento de inicio de edición, y lo otro es un timer. Sabras de otra alternativa??? Muchísimas gracias por el blog y por las respuestas oportunas...

    ResponderEliminar
  36. hola Pierina

    Hasta donde se no se me ocurre alguna otra alternativa mas que usar el keypress en conjunto al EditingControlShowing

    DataGridView – KeyPress detectar ENTER y busqueda

    o quizas algo como esto:
    [DataGridView] – Texto Celdas en Mayúscula

    Estos podrias ser de utilidad, pero como has comentado asignan el keypress a la celda.

    Otra alterntiva podria ser el control de las teclas a nivel del formularios, por supuesto habria que adaptarlo a tu necesidad, pero quizas la tecnica sea mas prolija de aplicar:

    [Winforms] Seleccionar Fila con ENTER – DataGridView y ListView

    saludos

    ResponderEliminar
  37. Hola de nuevo Leandro,

    Estoy con una aplicación donde uso BD Mysql, y quiero aplicar lo que muestras es esta entrada, pero no lo he logrado.
    Básicamente tengo unos datos en mi tabla y quiero mostrarlos en el grid, con combo.

    Utilice el siguiente código:
    Dim ds As New DataSet
    sql1 = "(Select icj_codigo, icj_nombre From DPCAJAINST) Union All (Select tdb_codigo, tdb_nombre From DPBANCOTIP)"
    ds = ExecuteDataset(cn, sql1)
    Dim combo1 As DataGridViewComboBoxColumn = TryCast(dg_prueba.Columns(0), DataGridViewComboBoxColumn)
    combo1.ValueMember = "icj_codigo"
    combo1.DisplayMember = "icj_nombre"
    combo1.DataSource = ds.Tables(0).DefaultView

    Dim ds1 As New DataSet
    sql1 = "Select vtd_tipo From ventad Where vtd_id = " & Me.dg_encab.SelectedRows.Item(0).Cells(1).Value
    ds1 = ExecuteDataset(frm_main.sispro, sql1)

    Me.dg_prueba.AutoGenerateColumns = False
    Me.dg_prueba.DataSource = ds1.Tables(0).DefaultView

    Para el caso del combo se cargan los valores, pero en el grid se crean tantas líneas como registros tengo en la BD pero cada celda está en blanco.

    Ojalá y puedas ayudarme.

    Gracias de antemano.
    Saludos,
    Conchi

    ResponderEliminar
  38. hola Conchi

    algo que veo extraño es que en la query que usas para cargar la grilla solo defines una columna en el select

    Select vtd_tipo From ventad Where ...

    veras que solo defines vtd_tipo

    si la grilla tiene asignadas las columnas en tiempo de diseño puede que al no encontrar informacion para bindearla no muestre nada

    prueba de agregar mas columnas a esta query, o sino usa el *

    Select * From ventad Where ...

    saludos

    ResponderEliminar
  39. Hola Leandro,

    Gracias por responder.
    Copiando el código me equivoqué, mi query real es:

    sql1 = "Select vtd_idd, vtd_tipo, vtd_bdesc, vtd_cuenta, vtd_fecha, vtd_numero, vtd_monto, vtd_comen From ventad Where vtd_id = " & Me.dg_encab.SelectedRows.Item(0).Cells(1).Value

    Y en mi grilla tengo 8 columnas creadas en tiempo de diseño, de las cuales la Columns(1) es el combobox sería mi vtd_tipo.

    Ahh, en el código que copie antes, puse Columns(0), pero es Columns(1), cuando estoy cargando el combo.

    Gracias de nuevo,
    Conchi

    ResponderEliminar
  40. Hola Leandro,

    Ya encontré el problema. Lo que pasó fue que no coloqué los DataPropertyName...

    Ahora te hago una nueva consulta:
    Cómo hago para colocar otro combo el cual mostraría información según lo seleccionado en el primer combo (de la misma grilla).

    Saludos y gracias!
    Conchi

    ResponderEliminar
  41. Hola Conchi

    Si revisas el historia de preguntas de este mismo articulos, veras que "mijares", me realizo la misma consulta, y podras ver debajo la respuesta.

    La verdad he intentado realizar un ejemplo que implique combos anidados en la grilla, pero es muy complejo, y el resultado obtenido queda muy mal.

    La grilla de por si no expone funcionalidad para implementar algo como esto adecuadamente, es por eso que ante estos casos que ya deja de ser algo simple cambies de tecnica.

    Edita el registro por fuera de la grilla, y luego al grabar la actualizas, los combos simples de winforms pueden ser anidados sin problemas.

    saludos

    ResponderEliminar
  42. hola leandro, mucho gusto gracias por siempre ayudar, varias veces he encontrado tu respuestas en foros, mi duda es fijate que estoy haciendo un gridview con un sqldatasource enlazado, pero necesito tomar el valor de los texbox que editado como puedo hacerlo no se donde estan essos textbox, ademas el boton de elimnar como lo genera automaticamente necesito como colocar un mensaje antes de eliminar y ademas esos texbox como no se donde estan necesito al actualizar las letras minusculas se vuelvan mayusculas gracias... ayudame por favor......

    ResponderEliminar
  43. En este ejemplo que colocaste del DataGridViewComboBoxColumn vi que lo tenes conectado a la base de datos por medio de LINQ en que me puedes ayudar para que la conexion no sea por linq

    parce vos sos un teso

    ResponderEliminar
  44. hola preiles

    Me extraña que hayas visto linq en este ejemplo, porque no hace uso en ningun momento de consultas linq.

    Veras que si se define una clase de acceso a datos de nombre ProductosDAL, la cual contiene metodo para el acceso a la db por medio de ado.net

    Pero en ningun momento estos usando linq

    Estas seguro que has visto este codigo ?

    saludos

    ResponderEliminar
  45. Saludos Leandro, tengo un dolor de cabeza porque no he podido entender los metodos que utilizas en la clase productoDAL, me pregunto si no hay una forma mas sencilla de obtener una lista de la base de datos, en mi caso solo necesito una lista de los valores de un solo campo.

    ResponderEliminar
  46. hola David

    Hay muchas formas de obtener la informacion, pero no todas brindan el nivel de control que uno busca

    Por ahi si vas a los dataset tipados podrias aplicar algo como esto:

    ADO.NET - Parte 1 - Recuperar Información Sql Server

    esto deberia ser mas simple

    saludos

    ResponderEliminar
  47. alguien tienes algun codigo tengo que modificar dentro dataGridView con conexion acces ???????
    modificar eliminar actualisar

    ResponderEliminar
  48. Hola Leandro, estoy usando C# y tengo en un datagridview 5 columnas con combobox, el tema es que aveces en dos o tres columnas en la misma fila tengo el mismo valor seleccionado
    ¿como hacer para que se combinen celdas (con combobox) adyacentes siempre que tengan igual valor?

    Gracias,

    ResponderEliminar
  49. Leandro, te hago una consulta, tengo un datagridview con una columna que es DataGridViewComboBoxColumn.

    La misma tiene en Items:
    0
    1
    2
    3
    4
    5

    Mi pregunta es, puedo hacer que siempre comience en 0?

    Pude hacerlo con las demás columnas de tipo DataGridViewTextBoxColumn, haciendo simplemente:
    row.Cells["Libres"].Value = 0;

    Pero con esta que es DataGridViewComboBoxColumn no sé cómo hacerlo.

    Muchas Gracias.
    Leandro.

    ResponderEliminar
  50. hola

    podrias aplciar dos tenicas

    - una la cometada aqui

    DataGridViewComboBoxColumn set default value?

    como veras la idea es que el CellFormatting sea quien asigna el valor de esa columna por defecto

    - la otra podrias ser que despues de cargar el grid, asignando su datasource recorras las filas y asignes el valor que deberia tomar el combo

    saluos

    ResponderEliminar
  51. Gracias, Leandro, lo de CellFormating sirvió para ponerle un valor inicial, pero cada vez que lo edito vuelve al mismo valor.

    ResponderEliminar
  52. hola

    ok si entiendo el tema es que el CellFormatting peude apuntar mas a temas de estilo del grid y no tanto a trabajar con datos de als celdas

    y la otra propuesta de recorrer el grid y asignar el valor?

    o sea seria

    DataGridView1.DataSource = dt;

    foreach(DataGridViewRow row in DataGridView1.Rows){

    row.Cells["nombrecolumna"].Value = valordefecto;

    }

    esto lo haces solo una unica vez cuando cargas el grid por eso el foreach esta debajo del Datasource

    saludos

    ResponderEliminar
  53. No hay caso, con el foreach me dice:

    "Se produjo la siguietne excepción en DataGridView:

    System.FormatException: El Valor del DataGridViewComboBoxCell no es válido.

    Para reemplazar este cuadro de diálogo predeterminado controle el evento DataError."

    foreach (DataGridViewRow row in dgvLocal.Rows)
    {
    row.Cells["Jugador"].Value = "Sin seleccionar";
    }

    ResponderEliminar
  54. hola

    cuando defines los datos del combo en la columna del grid asignas el ValueMember ?

    porque deberias asignar un valor coincidente con esto para que seleccione

    saludos

    ResponderEliminar
  55. Sí, lo hago, de hecho ni bien carga el Formulario todo el DataGridView en esa columna queda con lo que yo quiero ("Sin seleccionar"). Lo que pasa es que si hago click en el comboBox y elija lo que elija, siempre vuelve a "Sin seleccionar".

    ResponderEliminar
  56. hola

    pero al final lo implementas en un foreach luego de asignar el datasource y recuerdas quitar el CellFormatting ?

    no prefieres seguir el tema en los foros

    foro c#

    digo alli sino soy yo quien te ayude seguro alguien mas lo hace, quizas aporte algun punto de vista que se me este escapando

    saludos

    ResponderEliminar
  57. Lo puse en el foro pero comentaste vos sólo! jeje. No hay caso :(

    ResponderEliminar
  58. jeje si suele pasar, recuerda que pasado un tiempo y si has avanzado en conocimiento del problema podrias volver a preguntar en el foro, haciando referencia a la pregunta previa

    podrias en la nueva pregunta explciar las conclusiones a las que legaste, y ver si alguien se le ocurre algo adicional que probar

    saludos

    ResponderEliminar
  59. Hola amigo, me gustaría saber como puedo visualizar un campo a partir de otro; por ejemplo ingresar el codigo del producto en una columna y que en la siguiente columna muestre el nombre del producto al presionar enter. gracias por tu respuesta

    ResponderEliminar
  60. Hola leandro, tengo una consulta. Mira te comento, tengo una grilla donde tengo en una columna conceptos y en otra columna tengo un comboboxcolum donde cargo la valoracion de esos conceptos. Ejemplo: Concepto: Caja de motor. Valoracion: Bueno-Malo-Regular. es para realizar el peritaje de un vehiculo. yo en otra pantalla tengo un ABM de los conceptos con sus respectivas valoraciones.
    Yo lo que quiero es que segun el concepto que tengo en la columna conceptos del datagridview me filtre en el combo las valoraciones para ese concepto. No se si quedo claro. Espero tu respuesta.

    ResponderEliminar
  61. hola Piloni

    algo no se entendio, ese combo de conceptos donde esta ubicado? dentro del propio gridview junto al combo de valoraciones, o esta en otro formulario, y si es en otro form como llegas al mismo

    porque podrias al momento de abrirlo pasarle la seelccion del combo de valoraciones para aplciar un filtro en el WHERE de la query que carga los conceptos en ese segundo combo


    saludos

    ResponderEliminar
  62. Hola Leandro:
    Mi datagridview esta formado por una columna "Conceptos", otra columna que es del tipo Comboboxcolum "Valoraciones "y otra columna que se llama "observaciones".
    Yo quiero que segun el concepto, me filtre las valoraciones en el comboboxcolum.
    Yo he probado aplicarle el filtro al combo segun el concepto, pero el problema que tengo es que ese filtro me lo toma para todos los comboboxcolum. Mi ejemplo es muy similar al tuyo donde tu columna productos serian mis conceptos y tu comboboxcolum marcas serian mis valoraciones.
    Espero que se entienda. Saludos

    ResponderEliminar
  63. hola Piloni

    apuntas a algo como esto

    [DataGridView] DataGridViewComboBoxColumn – Variar contenido del combobox respecto a la fila

    como veras si puedes detectar la celda del combo en el grid tambien puedes definir el contenido del combo

    saludos

    ResponderEliminar
  64. Hola Leandro:

    Le hago una consulta.
    Tengo un Grid, donde la estoy llenando con un DataTable diractamente al DataSource de la Grid, luego agrego una columna DataGridComboBoxColumn desde código y le añado los datos a esa columna como lo indicaste en este ejemplo y muestra los datos correctamente.

    Lo que sucede es que si no se modifican los ComboBox de la Grid, la propiedad .Value del Combo no me cambia a la que tiene asignada al ValueMember, sino que sigue asignando la del DisplayMember.

    Esto lo digo porque necesito guardar el Id o el Código que este en esos momentos el Combo, asi el usuario no haya realizado cambios en el combo.

    Muchas Gracias

    ResponderEliminar
  65. hola Santiago

    no entendi, si defines el ValueMember entonces el combo deberia tomar este valor en el Value

    lo que me genera ruido es que estes creando esta columna despues de asignar los datos al grid


    saludos

    ResponderEliminar
  66. Hola Leandro

    Gracias por tu respuesta, efectivamente primero estoy agregando la columna y luego los datos, lo intentaré de nuevo.

    Santiago.

    ResponderEliminar
  67. Hola leandro me gustaria comentar que tus post son muy bueno y explicativos, queria hacerte una pregunta que en cierto modo esta relacionado cone ste post, bueno es lo siguiente:

    Yo tengo una clase Tabla con tres propiedades(nombre, id, campo), la propiedad campo es de tipo lista, es decir tengo otra clase llamada Campo la cual tambien tiene sus propios atributos y cuando cargo en un datagrid una lista de la clase tabla, en la columna que cargo los campo solamente me sale la palabra collection en cada fila y supomgo que es por que es una lista de campo por cada tabla, entonces me pregunto como hago para cargar solamente una tabla u id y todos los atributos de una tabla, buenoe spero que me comentes porfa es que tus post siempre me ayudan pero ahorita no se como hacer lo que te planteo, gracias de antemano por tus comentarios

    ResponderEliminar
  68. hola veronica

    El DataGridView no soporta la representacion de objeto complejos como listas, es por eso que no puede visualizar el datos

    podrias a la clase que usas en esa propiedad "campo" definirle el ToString para que el grid lo tome y represente

    public class Clase2{

    public override ToString(){
    return //aqui las propiedades de la clase
    }
    }

    y lo usas

    public class Clase1{

    public List<Clase2> ListClase2 {get; set;}
    }

    en el grid la lista de clase 2 se vera lo que definas en el ToString()

    saludos

    ResponderEliminar
  69. Hola leandro gracias por tu ayuda y de verdad te digo porfa nunca dejes de publicar tus post son buenisimos.

    ResponderEliminar
  70. Tambien se me olvido comentarte, que talvez algun dia podrias publicar algo sobre delegados en listas, Bye buenas tardes

    ResponderEliminar
  71. hola veronica

    que bueno que resulten utiles los articulo me pone contento

    lo que no entendi es que seria un delegado en listas
    porque un delegado se asocia a uan clase que puede definir una lista, pero noa una lista en si mismo, salvo que sea algina clase que herede de una lista

    saludos

    ResponderEliminar
  72. Hola, leandro con respecto a los delegados me referia a algo asi:
    List prueba = cmpoTabla.FindAll(delegate(Campo ca) { return ca.NombreCampo == "ruc"; });

    es decir tener una lista de las propiedades de una clase y poder filtrar un dato a traves de un delegate.

    Considero que son muy utiles y bueno pienso que tu podrias publicar otras utilidades de los delegados que sean importantes.

    Bueno solamente pienso que son interesante y por eso practicamente te sugeri que si podias escribir algo sobre ellos, pero nada mas, de todas formas siempre que busco algo me respondes usted con sus post.

    Buenas tardes, y muchas gracias por mantener siempre activos tus posts y atender las preguntas de quienes los visitamos.

    Saludos.

    ResponderEliminar
  73. hola veronica

    pero hay mejores formas de lograr eso mismo con expresiones lambda

    que seria

    var prueba = cmpoTabla.Where(ca => ca.NombreCampo == "ruc");

    Lambda Expressions

    los delegados de la forma en que lo has definido ya casi ni los uso con als expresiones lambda es mucho mas simples

    Nota: necesitas .net 3.5 o superior

    saludos

    ResponderEliminar
  74. Hola leandro como estas:

    Te escribo para hacerte una pregunta que no tiene nada que ver con este post, talvez me ayudas:

    quiero convertir una lista de propiedades en un dataset usando reflexiones, fijate que me encontre un codigo en: http://geeks.ms/blogs/crisfervil/archive/2011/07/06/convert-listagenerica-a-datatable.aspx

    este codigo me convierte una lista de propiedades en un datattable, y funciona muy bien para que esta muy bien codificado, pero para lo que yo deseo no me sirve, porque yo tengo una lista de propiedades en donde una de esas propiedades es de tipo lista entonces no me la puede agregar como una columna,eh ahi el problema, estas son mis propiedades:


    #region PROPIEDADES

    public string Esquema
    {
    get
    {
    return _esquema;
    }

    set
    {
    _esquema = value;
    this.NotifyPropertyChanged("Esquema");
    }
    }

    public string NombreTabla
    {
    get
    {
    return _nombreTabla;
    }

    set
    {
    _nombreTabla = value;
    this.NotifyPropertyChanged("NombreTabla");
    }
    }

    public bool Seleccionada
    {
    get
    {
    return _seleccionada;
    }

    set
    {
    _seleccionada = value;
    this.NotifyPropertyChanged("EstadoTabla");
    }
    }

    public BindingList Campos
    {
    get
    {

    ////if( _campos==null )
    ////{
    _campos=Campo.ObtieneCampoDeTabla(this.NombreTabla,this.Esquema);

    ////}
    return _campos;
    }

    private set
    {
    _campos = value;
    this.NotifyPropertyChanged("Campos");
    }
    }


    public string BaseDatos
    {
    get
    {
    return _bdTabla;
    }

    set
    {
    _bdTabla = value;
    this.NotifyPropertyChanged("BaseDatos");
    }
    }
    A como puedes ver una propiedad la que se llama campos es una lista de las propiedades de mi clase campo, asi que no como hacer para que me tome esa propiedad como una nueva tabla y tenr dos datatables relacionados en un dataset; espero no haberte confundido con tanta palabreria, si puedes contestame porfavor, ya he leido bastante pero no he podido hacer lo que deseo.

    Buenas tardes lenadro.

    ResponderEliminar
  75. hola veronica

    entiendo el problema, pero la verdad no lo veo nada simple, porque quieres crear estructura complejas en la transformacion, es mas cual seria el limite, que pasa si campos ademas tiene otras propiedades y esta a su vez otras y se ramificara, o sea la complejidad puede crecer demasiado, cuando se transforma este tipo de entidades se tienden a crear simples.

    no has evaluado ver si el CopyToDataTable() no lo soluciona, igualmente creo que no, pero no se pierde nada

    Linq DataSet – Agrupar y totalizar

    seria como explico en la segunda parte del articulo

    saludos

    ResponderEliminar
  76. Mi problema surge que tengo columnas ya puestas en modo diseño entonces lo que quiero hacer es llenar mediante un query ese query llena un datablae o un reader
    en el caso del reader me surge la idea de que dentro de un while :


    while(reader.read()){
    "Aqui iria el llenado del datagrid ?"

    }

    y como seria? para que sepa donde poner el dato y en que columna espeor me puedas ayudar :)

    ResponderEliminar
  77. hola Fernando

    el tema es que si usas un datareader deberias usar el Items.Add() para crear cada fila

    while(reader.read()){
    DataGridView1.Items.Add(new string[] { Convert.ToString(reader["nombrecampo1"]), Convert.ToString(reader["nombrecampo2"]), Convert.ToString(reader["nombrecampo3"])});
    }

    o sea pones cada valor del campo que conincida con la posicion de cada columna

    saludos

    ResponderEliminar
  78. ok entiendo pero en el caso de llenar un dataable con una consulta y hacer que coincidan las columnas que hice en diseño a las del databtable

    ResponderEliminar
  79. Espero me puedas ayudar a resolver mi duda sobre llenar mi datagrid view ya que las columnas ya las tengo en modod diseño pero las necesito llenar con una consulta

    ResponderEliminar
  80. hola Fernando

    has validaod que la propiedad DatapropertyName del grid coincida con el nombre de la columan del datatabla que asignas

    porque de esa forma mapeas el campo de datos con la columna del grid

    saludos

    ResponderEliminar
  81. si en ese sentido nada mas tengo que ponet datagridwiev1.datsource=datable;

    algo asi es que ya e llenado datagrid pero sin columnas ya establecidas



    aunque pude resolver la duda con el reader. al fin y al caso dan el mismo resultado no ?

    ResponderEliminar
  82. mm el datareader no es lo mismo que el datatable, porque imagino que con e reader usaste el Rows.Add() para crear cada row, cuando la idea es asignar el DataSource que seria lo correcto para vincular las columnas

    saludos

    ResponderEliminar
  83. y para asignar asi como le tengo que hacer ? me podrias orientar?

    ResponderEliminar
  84. Te comento que tengo mi codigo asi mira ..

    string sql = "Select a.idAlmacen, p.Nombre,t.tamaño as tamano,a.cantidad_almacen from almacen a join producto p on a.idProducto = p.idProducto join tamaños t on a.idTamaños = t.idTamaños where p.idProducto=(select idProducto from producto where nombre='" + listBox1.Text + "')";
    MySqlDataAdapter da = new MySqlDataAdapter(sql, conexion);
    DataTable dt = new DataTable();
    da.Fill(dt);
    dataGridView1.DataSource = dt;



    pero al hacer que funcione lo genero mediante la seleccion de un elemento de un listbox, pero ala hora de que se llene el datagrid solo pinta las filas pero no el contenido .

    ResponderEliminar
  85. me diras que como molesto pero XD ya consegui como pasar los datos, con un datatable y columnas creadas en diseño. Muchas gracias :)


    por cierto muy buen blog!

    ResponderEliminar
  86. hola Fernando

    porque usaste

    ... where p.idProducto=(select idProducto from producto....

    en lugar de aplciar un inner join ? o sea podrias haber realizado un join con la tabla de productos y aplciar un where simpel en lugar de una subconsulta

    ademas otro tema usa parametros, eso de concatener en un string el valor del listbox no es correcto

    saludos

    ResponderEliminar


  87. Hola Leandro,es manifico el aporte que realizas.

    Estoy teniendo un problema y me gustaria que me des una idea de como resorverlo o un ejemplo similar.

    Tengo que crear un formulario de ventas en el cual desde un datagreed yo pueda agregarle una fila cada vez que quiera agregar un articulo y en esta fila que haya un combo box o cuaquier otro control que me permita seleccionar entre las opciones el articulo que quiera agregar a la venta y que automaticamente me aparezca en la columna "precio" del datagred el precio del producto seleccionado, es algo muy similar a lo que expones aqui en este ejemplo, pero a diferencia necesito que se pueda agregar filas cada vez que se quiera agregar un producto a la venta y que aparezcan sus precios automaticamente y No que aparezcan todas cuando carga el form como es el caso del ejemplo.

    Te agradeceria bastante la ayuda.

    ResponderEliminar
  88. hola Carlos

    o sea algo como esto

    [N-Tier] – Desarrollo en capas - Ejemplo Facturación – Parte 3

    alli se van agregando filas de la factura a medida que se necesite

    saludos

    ResponderEliminar
  89. Hola de nuevo leandro, !!!Muchas Gracias este ejemplo explica exactamente lo que necesito, ya lo probé, sin embargo tengo un problema grave que no me ha dejado seguir.

    Como soy aun novato opté por trabajarlo solo en clases y no en capas
    Cuando en la primera fila que aparece por defecto en el combo box Trak puedo seleccionar el item que deceo y automaticamente me pone el precio, pero sin embargo cuando le doy clic al boton para "Agregar otra linea", se borra el item que habia seleccionado anteriormente y entonces quedan las dos flas en blanco, luego cuando intento seleccionar de nuevo en el combo box Trac que en mi caso se llama "Articulo", me lansa el siguiente error:

    "
    Unable to cast object of type 'SISTVENTAS.TrackEntity' to type 'System.IConvertible'.

    SISTVENTAS es el nombre del proyectO

    Por favor me podrias decir a que se deberia este error?

    Muchas Gracias


    ResponderEliminar
  90. hola Carlos

    es dificil decir que puede estar pasando sin analizar el codigo

    si se pierden los datos es porque quizas estas recargando el grid asignando un nuevo DataSource sin conservar el que ay tenias previamente.

    quizas para posterar codigo seria mejor que lo realices en el foro
    foro

    saludos

    ResponderEliminar
  91. Hola de nuevo Leandro.

    Muchas gracias buscando en el primero de tus ejemplo puede resorver el problema.

    Cuando lo realize sin capas si me funciona.

    Gracias, muchas gracias por ponernos a disposicion tus conocimientos.

    !!Que dios te bendiga

    ResponderEliminar
  92. Hola Leadro, he estado viendo tus publicaciones y me gustan mucho, que bueno que existan personas como tu que ayudan al desarrollo de los principiantes en esto de la programacion.

    Me gustaria consultarte un problema a ver si me puedes ayudar.

    Es que tengo que capturar la fecha y la hora en un formulario a una tabla de sql, necesito capurar la fecha y la hora actual mientras se ejecuta la aplicaicon y otra fecha y hora que yo le incerte, pero siempre que lo intento me da un error

    Me gustaria que enseñes y pequeño codigo con el formato que necesito darle para capturar la fechas y horas, ya sea en un maskedTextBox o en un dateTimePicker.

    Nota: el nombre de los campos en la tabla sql son
    fecha_registro: aqui tengo que capturar la fecha actual mientras se ejecuta

    fecha_entrada: aqui incerto una fecha y hora manual

    ambos campos son de tipo date time


    espero que me puedas ayudar.

    ResponderEliminar
  93. Me gustaria que me explicaras como hacerlo con un maskedTextBox.
    Gracias

    ResponderEliminar
  94. hola Andres

    para capturar la fecha del momento usarias
    DateTime.Now
    eso dara la fecha y hora actual

    despues para usar un control como ser el DatetimePicker podrias acceder a la propiedad Value

    DateTime fecha = DateTimePicker1.Value;

    eso es lo que asignarias al parametro de la query

    para el maskedTextBox solo es cuestion de definir un formato que tenga ##/##/####
    por supuesto el valor que tomes deberias convertirlo con el Convert.ToDatetime() para tener el tipo correcto que asignes al parametro

    saludos

    ResponderEliminar
  95. Muy buena explicación !!! una pregunta ¿se puede agregar un control button (no un columnbutton) en una celda específica del datagridview ?

    saludos

    Ian

    ResponderEliminar
  96. Muy buena explicación !!!! como solo tu explicas jejeje .. Leandro una pregunta ¿Se puede insertar un control button (no un columnbutton) en celdas específicas ? llevo tiempo intentandolo pero no puedo por que con el dtagridview.add(objButton); no deja especificar en que celda quiero insertar ... de hecho quiero llenar todo el datagridview de botones ...

    saludos

    Ian

    ResponderEliminar
  97. hola Ian

    imagino si vas a agregar un control deberias hacerlo en la celda en concreto, o sea:

    DataGridView1.Rows[index].Cells[index].Controls.Add(boton)

    aunque la verdad nunca lo he probado

    saludos

    ResponderEliminar
  98. hola leandro un gusto soy deyvi saavedra de peru necesito de tu ayuda urgente mira este post y ayudame sobre mi problema , es soibre datagridviewcomboboxcolumns saludos desde PERU-Piura
    http://www.foro.vb-mundo.com/f129/ayuda-datagridviewcomboboxcolumn-24708/#post92576

    ResponderEliminar
  99. hola Deyvi

    si pones un breakpoint en el codigo y pasas el mouse, o marcas

    row.Cells(id_cargo).Value

    y presionas Shift + F9 que valor obtienes ? es un valo numerico que representa el id o es una descripcion

    lo pregunto porque quizas cuando cargaste los items del combo que esta en la celda no definiste la propiedad ValueMember, si esto no se define entonces el value quizas no este devolviendo el id que necesitas para relacionar al insertar


    saludos

    ResponderEliminar
  100. ES UN VALOR NUMERICO, LO QUE QUIERO ES Q LOS DATOS DE LA GRILLA SE GUARDEN EN BD(TABLAPERSOA)AL DAR CLICK GUARDAR, PERO ESTOY LLAMADO LOS COMBOX DE LA GRILLA CON OTRA STABLAS (CARGO Y AREA) ASI : CLICK AQUI
    1- EL ERROR QUE SALE ES ASI: CLICK AQUI
    2- LO QUE ME PEDITES Q HAGA SE MUESTRA SI: CLICK AQUI

    ResponderEliminar
  101. hola leandro mira el administrador del foro me habloquedo mi post pero lo hevuelto de abrir este es el ensase
    http://www.foro.vb-mundo.com/f25/ayuda-datagridviewcomboboxcolumn-24709/#post92577
    por favor ayudame urgente

    ResponderEliminar
  102. hola Deyvi

    creo que deberias revisar donde debes poner las consultas en el foro vb-mundo porque tengo que darle la razon al admin por eliminarte la pregunta

    En la imagen "error.jpg" no logor ver que instruccion estas queriendo ejecutar, pero el mensajer indica que hay campos incorrecto

    saludos

    ResponderEliminar
  103. Gracias por la ayuda leandro
    saludos desde Peru - Piura
    el tema ya esta cerrado. Era error de de escritura jejeej gracias amigo leadro

    ResponderEliminar
  104. Hola Leandro quisiera preguntarte como podría crear un horario de clases en vb.net, algún consejo para poder desarrollarlo. saludos cordiales

    ResponderEliminar
  105. hola Claudio

    podrias usar algun control como ser

    https://bettercalendar.codeplex.com/

    para definir fechas y horarios lo veo muy practico y visualmente atractivo para las aplicaciones

    saludos

    ResponderEliminar
  106. Hola disculpa tengo una duda, es que estoy haciendo un pequeño programa de ventas ya logre guardar y buscar productos pero lo que no puedo hacer es como facturar dentro de un datagridview, la idea q tengo es editar la columna del codigo de producto y q la llenar la columna codigo de producto (cantidad )y dar enter me llene los demas campos como descripcion, precio y total estoy usando sql server 2008 y c# de antemano gracias por tu atencion espero q me puedas ayudar

    ResponderEliminar
  107. hola Juan

    podrias ahcer uso del evento CellEndEdit, en este evento podrias tomar el valor ingresado en las celdas para ir a buscar a la db la infromacion relacionada y completar los demas campo

    saludos

    ResponderEliminar
  108. Hola Leandro, gracias por este y los demas articulos, siempre me sirven....
    Una consulta con respecto a este articulo, cuando selecciono el un valor del combo (lo que seria un SelectedIndexChanged en un combo normal) puedo tomar el nuevo valor del combo mediante CellValueChanged; pero tengo que seleccionar el valor en el combo y luego quitar el focus del combo (hacer click en otro lugar que no sea el combo) para que se active el CellValueChanged. ¿Hay alguna forma de tomar el nuevo valor del combo apenas cambie se seleccione? al estilo SelectedIndexChanged
    Desde ya, muchas gracias

    ResponderEliminar
  109. hola Fer

    la verdad no intente resolver lo que planteas, no al menos en el combo, si lo habia visto con el checkbox

    [DataGridView] – Uso del CheckBox - DataGridViewCheckBoxColumn

    quizas si aplicas la misma tecnica se logre el efecto, pero no estoy seguro

    saludos

    ResponderEliminar
  110. Despues de mucho (mucho!!) buscar, encontre una solucion. Dejo el link http://www.vbforums.com/showthread.php?656274-RESOLVED-Datagridview-Combobox-SelectedIndexChanged

    El CellValueChanged no funciona hasta que el combo no pierde el foco, asi que no es inmediato; la solucion planteada en el link que dejo si funciona excactamente como el SelectedIndexChanged de un combo "normal"

    Saludos

    ResponderEliminar
  111. Hola buenas tardes :

    Estoy trbajando con DataGridViewComboBoxColumn, en un datagridview, pero tengo un problema, quiero filtrar un valor de una BD. el DataGridViewComboBoxColumn ya lo llene con datos. Pero al quererlo filtrar solo me trae el valor de la BD y quiero que se muestre ese valor en el DataGridViewComboBoxColumn, pero los otros valores ya cargados en el DataGridViewComboBoxColumn tambein se visulicen. el dato que filtro esta dentro de los valores ya cargados. gracias

    ResponderEliminar
  112. hola Angie

    no entendi el planteo, el combo solo permite ver un unico item a la ves, si dices que cargaste los items en el combo y se selecciona el que esta definido en la db entonces esta listo, porque asi es como funciona

    no puedes ver mas que un item en la dcelda del combo, solo cuando edites la celda es que aparecera el combo y podras seleccionar un item de la lista

    saludos

    ResponderEliminar
  113. Exelente todo funciona muy bien, pero me gustaria que me ayudaran para validar mi datagridview cuando no tiene datos que mostrar. me podrian ayudar porfavor!!!!

    ResponderEliminar
  114. hola ivette

    podrias definir el

    EmptyDataTemplate

    con eso defines un template cuando no hay datos

    saludos

    ResponderEliminar
  115. Buenos dias Leandro

    Necesito ayuda, mi problema es q necesito un datagridview o listview en el cual haya un combobox dentro del datagridview el cual(combobox) tenga datos personalizado para cada fila xq deseo que el combobox se llene con un procedure que busque como parametro la primera columna del gridview.

    los campos serian...

    id, descripcion, laboratorio, almacen...

    donde almacen es el combobox que contenga los almacenes en donde se encuentre el articulo, eso se buscaria x id.

    por ejemplo en un combo solo aparecera 2 almacenes, en otro 3 y otro 1, dependiendo del id del articulo, nose si pudieras ayudarme porfavor, seria de gran ayuda, grax de antemano.

    ResponderEliminar
  116. Buenos dias Leandro

    El proyecto que me enviaste, lo logro entender algo, pero tengo algunos inconvenientes, no me reconoce las clases telefono y SucursalesEntities, me podrías ayudar derrepente es que tengo el VS2012... tendrá algo que ver, gracias de antemano.

    ResponderEliminar
  117. creo que ya entendí... voy a probar, gracias, ah y tu blog es de muuucha ayuda, denuevo gracias

    ResponderEliminar
  118. Perdon pero sigo teniendo complicaciones con SucursalesEntities, si me pudieras explicar algo sobre eso te lo agradeceria mucho, gracias

    ResponderEliminar
  119. hola Pierre

    hay algun error que muestre el VS con esa clase de entidad ?

    saludos

    ResponderEliminar
  120. si, me dice el tipo sucursalentities no esta definido.. igual me pasa con telefonos

    ResponderEliminar
  121. hola Pierre

    has validado que el namespace donde defines las clases que tienen este problema sea el correcto? quizas falte definir algun using para que tome la definicion de estas clases

    imagino que el codigo que definen estas entidades lo tienes creado no ?

    saludos

    ResponderEliminar
  122. descargue tu ejemplo y solo lo abrí, y ahí si agarra, pero cuando intento copiando esos dos grupos de códigos y alterándolo respecto a mis datos no me resulta, donde me sale ese error es en private sub loadgrillacomboboxlocales, no entiendo mucho eso del namespace, pero me sale que esas clases no estan definidas, la SucursalesEntities y la de Telefonos, cuando pongo ir por pasos al proyecto que descargue y abrí me sale partial public class SucursalesEntities en SucursalesModel.Designer.vb pero no se muy bien como es eso... T_T

    ResponderEliminar
  123. pero creo q tiene que ver con el SucursalesModel.edmx... que es ese archivo

    ResponderEliminar
  124. hola Pierre

    si usas un edmx quiere decir que implementas entity framework

    valida si el namespace donde se creo es el correcto, usa el intellisense del VS para validarlo

    saludos

    ResponderEliminar
  125. copie todo lo de sucursalmodel.vb a una clase y ahora solo no me reconoce el where... me dice no es un miembro de 'Sucursalesentities.Telefonos'

    ResponderEliminar
  126. hola Pierre

    lo que estoy viendo es que en el codigo que implemente en el ejemplo no utilizo ningun edmx, sino que aplico aod.net simple recorriendo con un reader los registros y generando los objetos de la entidad

    no logro ver que es lo que estas copiando, si usas un edmx deberias aprender a usar entity framework y linq para poder consultar los datos, porque esto reemplaza la persistencia que yo implemente en este articulo

    saludos

    ResponderEliminar
  127. ahh el .edmx es como una base local y si quisiera sin edmx como podria, sql xq parece q eso lo creo automaticamente el sucursalmodel.edmx... gracias por la molestia de tomarte un tiempo.

    ResponderEliminar
  128. no... es sobre tu otro post.. este me recomendast


    http://ltuttini.blogspot.com.ar/2010/05/datagridview-datagridviewcomboboxcolumn.html

    ResponderEliminar
  129. en .net lo estoy haceindo asi que segui tu ejemplo de .net

    ResponderEliminar
  130. hola Pierre

    el edmx no es una base de datos local, sino que es entity framework, o sea es un ORM que usas para acceder a los datos

    en la ultima parte me perdi un poco que es lo que buscabas

    saludos

    ResponderEliminar
  131. hola leandro

    Aun no logro hallar la solucion, si me podrias ayudar, gracias.

    ResponderEliminar
  132. hola Pierre

    pues la verdad no sabria como

    si usas un diagrama de entity framework deberias antes conocer como utilizarlo para poder incorporarlo al desarrollo, porque la tecnica en como trabajas con la UI no varia, solo estas cambiando como obtienes los datos

    saludos

    ResponderEliminar
  133. Ya resolví sobre el combobox en mi datagridview, pero tengo una consulta, como podría restablecerle un index a esos combobox, porque en un combobox solo pondría combobox.selectedindex=1, o el q desee pero en el combo dentro del datagridview no tiene esa propiedad... si supieras y pudieras ayudarme, te lo agradeceria

    ResponderEliminar
  134. hola Pierre

    en el grid solo basta que asignes el Value de la celda para que este seleccione el item del combo que tiene ese valor

    no selecciona por index, sino por valor

    saludos

    ResponderEliminar
  135. Buenas Leandro

    Grax x el dato, pero como haria si quisiera ponerle a todos los combo el primer registro y los valores q tienen cada combobox es diferentes, en uno x ejemplo tiene los datos (Alex, Jorge, Luz) y el Otro (Pierre y Victor) como valores como podria hacer para q aparecieeran por defencto los primeros...

    grax.

    ResponderEliminar
  136. hola Pierre

    analiza

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/18e3097b-4de1-4e2b-9046-ef1e890a1ce1/datagridview-combobox-selected-item

    donde hace

    cell.Value = cell.Items[0];

    veras que alli asigna como valor el primer item

    saludos

    ResponderEliminar
  137. Honor, A quien Honor merece Sr. Leandro, Saludos.
    He encontrado mucha ayuda de parte suya a personas que la necesitamos.
    Hoy soy una de ellas.
    Tengo este pequeño codigo que no acepta dos espacios en blanco seguidos.
    Private Sub SinDoblesEspacios(ByVal e As System.Windows.Forms.KeyPressEventArgs)
    If Asc(e.KeyChar) = 32 Then
    i = i + 1
    If i > 1 Then
    e.KeyChar = Chr(0)
    End If
    End If
    If Asc(e.KeyChar) <> 32 Then
    If Asc(e.KeyChar) <> 0 Then
    i = 0
    End If
    End If
    End Sub

    Pero mi necesidad es en una celda de un datagridview.
    Espero que me ayude.
    Gracias.
    Ejemplo Valido: Gilberto Reyes Ruiz a sus ordenes.
    Ejemplo NO Valido: Gilberto Reyes Ruiz a sus ordenes.

    ResponderEliminar
  138. Pues mire que casualidad.
    El comentario que mande.
    muestra mi requerimiento.
    mande Ejemplo NO valido con dobles espacios y no aparecieron.
    Digame como le hago en una celda.

    ResponderEliminar
  139. hola gilberto

    una duda, has encontrado la forma de validar espacios en blanco en un textbox simple ? porque si lo haces para este aplciarlo a una celda es directo ya que trabajarias con el
    EditControlShowing para poder adjuntarte al keypress de la celda

    ---

    http://social.msdn.microsoft.com/Forums/es-ES/a876977f-42a8-4b5b-8d56-25ebb7a5a71c/quitar-espacios-en-blancos-sobrantes-entre-palabras

    tambien podrias dejarlo escribir lo que necesite y despues en el evento CellEndEdit eliminas los espacios dobles que se hayan ingresado

    saludos

    ResponderEliminar
  140. Gracias Leandro.
    Si me sirbio de ayuda tu comentario.
    nos vemos en la proxima.

    ResponderEliminar
  141. Hoye leandro otra pregunta.
    Siempre cuando hago cambios en un datagrid en modo programación se me borra todos los datos que contiene la base de datos.
    y mi temor es cuando mi aplicacion ya este en produccion, y tenga que hacer alguna modificacion perder toda esa informacion, como resolver eso?
    saludos..

    ResponderEliminar
  142. hola gilberto

    la base de datos esta integrada al VS, o sea puedes verla en el solucion explorer

    porque si es esi recuerda que el VS crea una copia al \bin\Debug y trabaja con esta, por lo que en cada ejecucion que realizas con F5 en el VS crea una nueva copia pisando la anterior

    esto sucede solo mientras estes integrado al VS, despues al hacer deploy en el cliente ya no sucedera

    saludos

    ResponderEliminar
  143. Hola Leandro es un gusto para nosotros ver tus Tutos....Tengo una consulta, como puedo hacer un datagrid como analisis de antiguedad de saldos de una cartera de clientes, si los datos los tengo a nivel de documentos(Facturas x Clientes) tengo una N cantidad de datos por cliente, ppor lo que necesitoo agruparlos en un Datagrid que lleve consigo totales, vencido y Mora a 30 y asi sucecivamente, tengo u codigo el cual para hacer las columnas calculadas tuve que hacer varias sentencias SQL(Select), por ende varios DataAdapter, por lo que al momento de presentar la consulta hay datos repetitivos como nombre y codigo de cliente....no se si me explique bien...trabajo con Visual Basic 2010 y bases de datos access
    Este es mi codigo

    atte.

    Jose Giron (Honduras)

    Private Sub llenaGrid() 'datos para llenar el data grid

    Dim ds As New DataSet
    Dim dt As New DataTable
    Dim Strsql As String = "SELECT Idpersona, Nombres, SUM(importe) AS Total from Persona GROUP BY Idpersona,Nombres"
    'Dim Strsql2 As String = "SELECT Idpersona, Nombres, SUM(Importe) AS Vencido from Persona Where Dias_Mora >0 GROUP BY Idpersona,Nombres"
    Dim Strsql3 As String = "SELECT Idpersona, Nombres, SUM(importe) AS Vencido_30 from Persona Where Dias_Mora >=0 and Dias_Mora <=30 GROUP BY Idpersona,Nombres"

    Dim adp As New OleDb.OleDbDataAdapter(Strsql, conn)
    Dim adp2 As New OleDb.OleDbDataAdapter(Strsql2, conn)

    ds.Tables.Add("Tabla")

    adp.Fill(ds.Tables("Tabla"))
    adp2.Fill(ds.Tables("Tabla"))
    adp3.Fill(ds.Tables("Tabla"))

    Me.DataGridView2.DataSource = ds.Tables("Tabla")

    End Sub



    ResponderEliminar
  144. Hola Leandro es un gusto para nosotros ver tus Tutos....Tengo una consulta, como puedo hacer un datagrid como analisis de antiguedad de saldos de una cartera de clientes, si los datos los tengo a nivel de documentos(Facturas x Clientes) tengo una N cantidad de datos por cliente, ppor lo que necesitoo agruparlos en un Datagrid que lleve consigo totales, vencido y Mora a 30 y asi sucecivamente, tengo u codigo el cual para hacer las columnas calculadas tuve que hacer varias sentencias SQL(Select), por ende varios DataAdapter, por lo que al momento de presentar la consulta hay datos repetitivos como nombre y codigo de cliente....no se si me explique bien...trabajo con Visual Basic 2010 y bases de datos access
    Este es mi codigo

    atte.

    Jose Giron (Honduras)

    Private Sub llenaGrid() 'datos para llenar el data grid

    Dim ds As New DataSet
    Dim dt As New DataTable
    Dim Strsql As String = "SELECT Idpersona, Nombres, SUM(importe) AS Total from Persona GROUP BY Idpersona,Nombres"
    'Dim Strsql2 As String = "SELECT Idpersona, Nombres, SUM(Importe) AS Vencido from Persona Where Dias_Mora >0 GROUP BY Idpersona,Nombres"
    Dim Strsql3 As String = "SELECT Idpersona, Nombres, SUM(importe) AS Vencido_30 from Persona Where Dias_Mora >=0 and Dias_Mora <=30 GROUP BY Idpersona,Nombres"

    Dim adp As New OleDb.OleDbDataAdapter(Strsql, conn)
    Dim adp2 As New OleDb.OleDbDataAdapter(Strsql2, conn)

    ds.Tables.Add("Tabla")

    adp.Fill(ds.Tables("Tabla"))
    adp2.Fill(ds.Tables("Tabla"))
    adp3.Fill(ds.Tables("Tabla"))

    Me.DataGridView2.DataSource = ds.Tables("Tabla")

    End Sub



    ResponderEliminar
  145. Hola Leandro:

    Estoy mirando tu blog para ver si encuentro lo que necesito. Estoy trabajando con unas columnas combo en un Data Grid ya logre cargar los valores en todas ellas y funcionan bien. El tema es que quiero que cuando se crea una nueva fila la columnas Combo me muestren inicialmente un valor de las mismas.

    La verdad que intente varias cosas pero todas me dan error por distintos motivos. En algunos momentos es que no se creo el objeto y la verdad tampoco tengo idea muy bien con que evento probar, el de Formateo de la celda cuando trato de ver la columna en que estoy me da un null al obtener la cerda actual. Y si intento hacer algo en el evento de creación de la fila después cuando me muestra la celda me da error de formato. La verdad es que estoy un poco perdido con esto.
    Desde ya muchas gracias.

    ResponderEliminar
  146. hola Javier

    el inicializar un valor en un control combo en el grid podrias hacerlo en el evento RowDataBound, alli usarias el FindControl() y localizas el combo para asignarle el valor que quieres tenga por defecto seleccionado

    lo que no me quedo muy claro es el tema del formato pero recuerda que puedes usar el

    GridViewRow.DataItem (Propiedad)

    para obtener los valores originales que forman la row del grid y de alli tomar el valor que asignes al combo en el SelectedValue

    saludos

    ResponderEliminar
  147. Buen dia Leandro necesito que me ayudes con tus conocimientos, necesito hacer un análisis de antiguedad de saldos en VB, mi base tiene códigos de clientes, números de factura, importe por factura y lo mas importante la demora de cada factura, con esto necesito hacer un análisis de antigüedad que diga, Codigo de cliente, total pendiente, vencido a 30, vencido a 60 etc.

    Mi incógnita esta en el Select que tengo que hacer ya que no veo la forma de como iría el where ya que necesito que diga where demora >1 y asi sucesivamente.

    No se si me explique bien, espero me puedas retroalimentar..atte Jose Giron desde Honduras

    ResponderEliminar
  148. Buen dia Leandro necesito que me ayudes con tus conocimientos, necesito hacer un análisis de antiguedad de saldos en VB, mi base tiene códigos de clientes, números de factura, importe por factura y lo mas importante la demora de cada factura, con esto necesito hacer un análisis de antigüedad que diga, Codigo de cliente, total pendiente, vencido a 30, vencido a 60 etc.

    Mi incógnita esta en el Select que tengo que hacer ya que no veo la forma de como iría el where ya que necesito que diga where demora >1 y asi sucesivamente.

    No se si me explique bien, espero me puedas retroalimentar..atte Jose Giron desde Honduras

    ResponderEliminar
  149. hola Jose

    pero para poder calcular una antiguedad requieres de alguna fecha
    o sea deberias definir un campo que sea la fecha en que se crea el registro para poder restar esa fecha con la fecha actual y obtener asi la demora

    a donde apunto es que la demora no deberia ser un campo con un valor numerico, sino que deberia ser una fecha en donde la resta daria la demora

    saludos

    ResponderEliminar
  150. Gracias Leandro, las fechas las tengo, y la resta de la que tu hablas es la demora, ahora bien el dilema lo tengo en la consulta para mostrar los datos del importe por separado en columnas distintas de acuerdo a la antiguedad de los saldos ve este ejemplo que he preparado



    Base de Datos Tabla CuentasxCobrar
    Codigo_Cliente Factura Importe Vencimiento_Dias
    1 2001 100 10
    2 2002 200 20
    1 2003 100 68
    4 2004 200 98
    2 2005 200 50


    Requerido
    Codigo_Cliente Total Vencido 1 30 Vencido 31 60 Vencido 61 90 Vencido 91 120
    1 200 100 0 100
    2 400 200 200 0
    4 200 200

    El problema que tengo es que no se como iria la parte de la consulta, ya que solo la se hacer mostrando o creando una sola columna para la parte de importe tomando como referencia la demora de la factura.

    Dim Strsql As String = "SELECT Distinct Codigo_Cliente, Sum(Importe) As Total_Vencido
    "FROM CuentaxCobrar
    "WHERE Vencimiento_Dias > 0 GROUP BY Codigo_Cliente
    aquí solo me sale una columna, que hago para agregar las demas

    ResponderEliminar
  151. hola buen dia Leandro una consulta, se que no es el foro correcto pero necesito que me ayudes con algo,

    Estoy imlementando en un proyecto de VS 2010(Visual Basic) reportes de Crystal Reports y tengo problemas al publicar mi proyecto para hacer el Click Once, ya que probe instalarlo y no me deja entrar a las pantallas que estan las alplicaciones con Crystal reports, las demas si las puedo ejecutar o mas bien las puede ejecutar en la otra PC que lo he inctalado.

    el error al publicar es:
    La ubicación de instalación de los requisitos previos no se estableció en el sitio web del proveedor de componentes ni el archivo 'Crystal Reports for .NET Framework 4.0\CRRuntime_32bit_13_0_1.msi' del elemento 'SAP Crystal Reports Runtime Engine for .NET Framework 4.0' se encuentra en el disco. Vea la Ayuda para obtener más información.


    El punto es que en otro blog que tu referiste mire que habia que copiar de la carpeta donde esta el instalador del runtime que aparece en el error que es el e 32 bits, pero en mi pc solo tengo el de 64 y otro que dice CrystalReportsForVisualStudio, agregue los dos ya que antes aparecia el error de 64 bits pero como le digo no tengo el de 32 y el error perciste.

    No se si me explique bien, me gustaria que me heche una mano como es de costumbre

    ResponderEliminar
  152. hola Jose

    de este link

    http://1800thenerd.wordpress.com/2010/11/24/sap-crystal-reports-for-visual-studio-2010-files-needed-to-download/

    podrias obteber el msi para incluir en la instalacion

    es que la creacion del instador detecta un dependencia la cual no encuentra de donde obtener el paquete de instalacion para poder ubicar los componentes de crystal en el cliente

    saludos

    ResponderEliminar
  153. Hola Leandro ,en el caso que uno no tenga enlazado a una base de datos,por ej. tengo un combo similar a este.

    Dim numbers As New Collection
    For i As Integer = 1 To 100
    numbers.Add(i & " ingrediente/s")
    Next
    cmb_agentes.DataSource = numbers

    como se le puede indicar el datasource a una columna datagridviewcomboboxColumn? Estuve siguiendo tu ejemplo pero en mi caso al no estar vinculado a la base de datos nose como integrarlo al datagridview

    ResponderEliminar
  154. hola Andres

    porque simplemente defines un objeto collection en lugar de hacelro con un List(Of ) de una clase tipada

    apunto a que crees una clase del tipo

    Public Class Dato
    Public Property Key As Integer
    Public Property Value As String
    End Class

    entonces en el for cargas items a la List(Of Dato)
    como es una lista tipada podrias usar las propeidades para asignar el DisplayMember y ValueMemeber

    saludos

    ResponderEliminar
  155. Dim temp As New List(Of Dato)
    For i As Integer = 1 To 100
    temp.Add(New Dato
    (i, "ingrediente/s"))
    Next

    For Each item As Dato In temp
    'MsgBox(item.Key & " " & item.Value)
    Next
    Ahi lo pude mostrar,me faltaba el constructor de la clase,asi como el msj como le podria pasar para que eso sea el displaymember y el valuemember seria item.key,pero me queda la duda,esto seria dentro del bucle? porque si lo dejo afuera pierdo la referencia de item y como le paso al datasource de la DataGridViewComboBoxColumn?

    ResponderEliminar
  156. hola Andres

    pero has analizado el codigo de este mismo articulo? lo pregunto porque es justo la forma en que lo realizo

    si analizas las lineas

    DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns["Marca"] as DataGridViewComboBoxColumn;

    comboboxColumn.DataSource = ProductosDAL.GetAllMarca();
    comboboxColumn.DisplayMember = "Descripcion";
    comboboxColumn.ValueMember = "IdMarca";

    alli defino el combo de la columna del grid

    saludos

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

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

    ResponderEliminar
  159. Hola Leandro te queria comentar ya lo puedo mostrar al combo en la grilla,el problema es que por ej es un form que realizo un alta.Pero al querer volver a crear un detalle en la grilla,me tira un error ,me dice que ya existe la columna que quiero agregar,es la del combo,Como puedo eliminar la columna esa o de todas formas limpiar el datagridview de cualquier elemento que tenga,ya sea celdas textbox,combobox o checkbox.Esto deberia hacer cuando de de alta un registro con los datos de la grilla.Probe haciendo que el datasource del control datagridview sea nothing y tambien eliminando la columna que da problemas que es la del combo. asi : DGV_1.Columns.RemoveAt(6) ,en Ambos casos no pude eliminar esa columna.Lo unico que la agrego por codigo a esa columna y le indico que elementos va a tener el combo con un bindingsource

    ResponderEliminar
  160. hola como hago para enviar la descripción de un botón a un datagridview al dar click

    ResponderEliminar
  161. ¿como pasar la información de un botón a un datagridview en C#?

    ResponderEliminar
  162. hola Jimmy

    pues la verdad no se si entendi lo que quieres lograr

    partamos de la base que un boton no tiene ninguna informacion, quizas un TextBox o una query a una db podria proporcionarla, un boton solo es una accion y nada mas

    ahora si la idea es poner datos a un row existente quizas podrias hacer

    DatagridView1.Rows[index].Cells["nombrecol"].Value = TextBox1.Text;

    pero la verdad no se s es esto lo que buscas porque no esta muy clara la consulta

    saludos

    ResponderEliminar
  163. Hola leandro
    cuando tengo un combobox normal y lo lleno con datos de una base de datos, asi

    cboCurso.DisplayMember = "Nombre";
    cboCurso.ValueMember = "idCursos";
    cboCurso.DataSource = tb;
    para obtener el value member de dicho combobox solo me basta con
    cboCurso.SelectedValue y obtengo su valor ahora bien cuando tengo
    un combobox dentro de un Datagridview

    DataGridViewComboBoxColumn comboboxColumn = dataGridView1.Columns[1] as DataGridViewComboBoxColumn;
    la forma de llenar es similar, pero como obtengo el valor en este caso el idCursos

    comboboxColumn.DisplayMember = "Nombre";
    comboboxColumn.ValueMember = "idCursos";
    comboboxColumn.DataSource = tabla;

    ResponderEliminar
  164. hola David

    lo obtienes por medio del Value de la celda

    int id = Convert.ToInt32(dataGridView1.CurrentRow.Cells[1].Value);

    saludos

    ResponderEliminar
  165. Hola Leandro
    mi consulta seria como colocar una lista en el combos que se encuentra en dentro de la datagridview, serioa solo para visualizar .

    ResponderEliminar
  166. hola Yohana

    no entendi, lo que defines es una lista en las celdas del grid, por eso la columnas es un DataGridViewComboBoxColumn

    ademas si vas a poner una lista debes ponder editar la celda, no hay opcion de visualizar solamente porque sino permites editar no podras deplegar las opciones

    saludos

    ResponderEliminar
  167. Hola Leandro, soy abel, he intentado seguir tu ejemplo y adaptarlo a lo que yo quiero pero me resulta muy difícil ya que no entiendo mucho y soy nuevo en esto.

    Necesito que el dataGrid me carge un combobox como en el ejemplo desde una base de datos (yo uso SQLite), y que al seleccionar una referencia de producto me rellene las distintas grillas. Todo esto lo estoy haciendo en el CellValueChanged

    Consigo cargar correctamente en la columna Referencia el combo donde salgan todos las referencias de producto, mi pregunta es, una vez seleccionado el valor del combo como le digo que me rellene las diferentes columnas?

    Me creo un DataGridViewCell celda = dataGridView1.CurrentCell;

    y quiero que me diga la referencia que ha seleccionado la compare en la base de datos para coger los datos y cargarlos en las demas columnas. Por ejemplo si selecciona la ref1 que escriba el nombre del producto y su pvp

    Un saludo y grácias :)

    ResponderEliminar
  168. hola Abel

    podrias analizar [DataGridView] - Parte 6 - ComboBox y evento SelectedIndexChanged

    como veras podrias usar el CurrentRow para tomar la row que lanza la accion y asignar por el nombre de la columna el valor para completar los datos segun la seleccion

    saludos

    ResponderEliminar
  169. Hola Leandro,

    Muchas gracias por tu apoyo, me ha ayudado mucho en el auto aprendizaje de VB.NET durante mucho tiempo.

    Tengo este inconveniente, necesito cargar un grid con un datatable, pero uno de esos campos quiero que sea un combobox y cuando traiga los datos de la bdd, esté la información del campo seleccionado y cuando no traiga nada tenga el listado completo.

    En el ejemplo que tengo se carga por un lado el campo de la bdd y en otra columna el combobox y quiero que sean uno solo

    Muchas gracias

    ResponderEliminar
  170. hola Patricio

    si defines una columna del tipo combobox en la celda del grid esta tendra simpre el listado completo, solo que seleccionara cual de estos coincide con el dato que se asigne del datasource

    no puede ser uno solo porque son dos operaciones diferentes, una es la carga del combo y la otra la del grid, los datos se obtiene de tablas distintas

    saludos

    ResponderEliminar
  171. Hola Leandro,

    Muchas gracias por tu respuesta, descargué el ejemplo y eso es lo que necesito; pero habrá una forma de definir el grid en tiempo de ejecución y no de diseño como lo haces en el ejemplo.

    Gracias

    ResponderEliminar
  172. hola Patricio

    como poder se puede solo es cuestion de crear la instancia del DataGridViewColumn que necesitas, asignarle las propiedades y ponerlo en la coleccion de columnas del grid

    DataGridView__Column col = new DataGridView__Column();
    //aqui defines propiedades
    DataGridView1.Columns.Add(col);


    esto por supuesto lo realizas antes de asignar el DataSource

    saludos

    ResponderEliminar
  173. Hola yo quiero cargar dos datagridview en una misma ventana a la hora que inicia.. como puedo hacer

    ResponderEliminar
    Respuestas
    1. hola
      Si conoces ado.net solo es cuestion de definir dos queries, cargas dos datatable y asignas estos al DataSource de cada grid
      esto lo implementas en el Load del form
      saludos

      Eliminar
  174. Excelentes ejemplos, contienen mucho detalle, realmente son muy útiles.
    Muchas gracias

    ResponderEliminar
  175. Hola, tengo un problema. me da error cuado carla lo datos segun el id del registro, osea que quiero que me aparescar en load el dato del registro actual,

    ResponderEliminar
    Respuestas
    1. hola
      cual seria el problema ? sin codigo que estas implementando o sin siquiera el mensaje del error mucho no puedo decirte
      saludos

      Eliminar
  176. Hola, tengo un problema. me da error cuado carla lo datos segun el id del registro, osea que quiero que me aparescar en load el dato del registro actual,

    ResponderEliminar
  177. buenas noches, necesito desplegar una lista de datos, en una celda de un datagridview y luego que se despliegue seleccionar un dato y que ese dato se ubique en esa celda. Por favor digame si este ejemplo que menciona pudiera solventar lo que necesito. Este es mi email. bolivarcrosamaria@gmail.com

    ResponderEliminar
  178. Leandro muy buenos tus aportes para aquellas personas que estamos comenzando en esto de la programación, tengo el siguiente problema tengo un formulario el cual se llena con información de dod tablas por ejemplo: tabla_personas y tabla_pais, en donde los paises los tengo en un combobox pero cuando busco una persona necesito que el combobox ya venga mostrando el pais al que pertenece la persona.... espero ser lo más claro posible y espero vuestra ayuda... Desde ya Muchas gracias..

    ResponderEliminar
  179. Leandro muy útiles tus ejemplos mil gracias; pero tengo una consulta capaz q sea boba pero he hecho varias cosas y aún sigo sin dar con una solución. te explico cuando traigo los datos al datagridview, no quiero que seleccione ninguna fila, pero igual me selecciona la primera fila. he colocado esto en el load del form
    dg.ClearSelection()
    existira otra cosa?.
    por que no quiero seleccionar nada, ya que tengo alertas en el datagridview.
    saludos...

    LCM

    ResponderEliminar
  180. Para capturar el cambio del combo te falta usar el evento CurrentCellDirtyStateChanged, este fuerza a que aya un cambio en la grilla y a su ves llame al cellvaluechanged.
    Saludos

    ResponderEliminar
  181. Estimado

    Eres un genio... no sabes cuanto me han ayudado tus post.... Gracias eternas y Bendiciones para ti

    saludos cordiales desde chile....!!!

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

    ResponderEliminar
  183. Buen dia compañero, tengo una duda, sabe que al igual que mis compañeros también implemente su ejemplo en mi proyecto se lo platico a groso modo. tengo un grid donde le estoy cargando 3 columnas con los datos de un datatable llamado Dttraslado : fecha, numero_control, nombre, y turno

    la datatable Dttraslado tiene una consulta a la base de datos de 3 tablas que me regresa varias columnas. pero de todos los datos que me regresa, unicamente me interesa mostrar el el grid los datos mencionados arriba.
    todo esto se hace correctamente

    en el grid la columna turno me interesa llenarla con la consulta de una tabla en la base de datos que se llama turno, la cual me mostrara dos campos de la tabla(id_turno,turno) en el combo: valuemember: id_turno y displaymember: turno. esto lo puedo hacer correctamente también utilizando un datatable y asignándole al combo en el datasource el datatable turno.

    mi problema es que en el grid no se esta seleccionando el campo turno de acuerdo al id del turno seleccionado si no que solo me muestra todos los valores normalmente.

    le pongo mi consulta sql realizada a las tres tablas:
    "SELECT e.id_empleado, te.fecha, a.nombre_area , e.numero_control,e.nombre,ciudad.nombre_ciudad, c.nombre_colonia, d.direccion_completa, turnos.id_turno,turnos.hora,sb.id_serviciobrindado,sb.servicio_brindado FROM empleados as e LEFT JOIN direcciones as d ON e.id_empleado=d.id_empleado LEFT JOIN ciudad on d.id_ciudad=ciudad.id_ciudad LEFT JOIN colonia AS c ON d.id_colonia=c.id_colonia left join area as a on e.id_area=a.id_area INNER JOIN translados_extraordinarios as te ON te.id_empleado=e.id_empleado INNER JOIN turnos on te.id_turno=turnos.id_turno INNER JOIN servicio_brindado as sb ON sb.id_serviciobrindado=te.id_serviciobrindado and te.fecha='fecha_a_seleccionar' ORDER BY `d`.`id_empleado` ASC"

    de esta consulta yo estoy metiendo en el grid solo los campos fecha, numero_control, nombre, y id_turno en la propiedad dataproperty y todo lo hace bien

    le muestro la consulta sql numero dos:
    "SELECT id_turno, hora FROM `turnos` ORDER BY `turnos`.`hora` ASC"
    y esta consulta la meto al datasource del combobox.

    el detalle es que en el combo del datagrid no me esta seleccionando el id_turno donde debe de ser, sino que me llena unicamente con la consulta

    ResponderEliminar
    Respuestas
    1. Saludos compañero para comentarme que ya resolvi el problema. todo estaba bien, solo que estaba consultando una base de datos de respaldo que tengo y tenia que consultar la base de datos original, que es donde tengo los campos bien actualizados, me novatie yo mismo jeje. una disculpa, pero igual seguimos a la orden

      Eliminar
  184. Buenas,

    por motivos laborables estoy tratando de realizar esto que comentas, incluir un combobox en un datagridviw pero, llevo mucho tiempo intentándolo y no consigo sacarlo. Me gustaría a ver si pudieras ayudarme a realizarlo.

    Te cuento. Yo vuelco todo en bloque en un list al datagridview, puede que por aquí esté el fallo, en una clase pública que he definido:

    public class TransferAction
    {
    public string CustomeName { get; set; }
    public string CustomeOp { get; set; }
    public DataGridViewComboBoxColumn CustomeAccount { get; set; }
    public decimal CustomeAmount { get; set; }
    }

    Pero no lo consigo, a través de una función extraigo otro List con AccountCmr que reconvierto a un ComboAccount definido como DataGridViewComboBoxColumn:

    ComboAccount.Items.AddRange(AccountCmr);

    Y luego realizo el Add:

    actios.Add(new TransferAction() { CustomeName = this.ChainCustomer, CustomeOp = this.ChainOperation, CustomeAccount = ComboAccount, CustomeAmount = this.Amount});

    Y no extraigo nada.... Llevo tiempo intentándolo, mirando tutoriales, pero no puedo con ello....

    ResponderEliminar
  185. Buenos dias amigos, espero puedan ayudarme, explico mi caso:
    Tengo un form principal (Pedidos) el cual se carga en base a una cotización, trae los datos de cabecera y del detalle(en un DataGridView) hasta ahí todo bien; pero en este mismo form (Pedidos) también se pueden crear pedidos directos (sin cotización) para este caso tengo un boton que me trae un maestro de productos(form Productos) que al seleccionar los productos estos se agregan al DataGridView (Detalle), el primer error que me daba era al momento de traer los registros del grid productos al grid detalle (error: el grid detalle no tiene columnas, no puede agregar un fila), ahora en el metodo de agregar filas primero creo la columnas y luego agrego la fila, el problema esta que crea tantas columnas como filas tenga, si llevo la creacion de columnas antes del foreach... me da este error: Información adicional: Al control DataGridView no se puede agregar ninguna fila que no tenga columnas. Las columnas se deben agregar primero, cualquier ayuda al respecto se agradece.
    Gracias

    ResponderEliminar
  186. Buenos días tengo un problema ¿Como puedo cambiar una columna texto a una columna ComboBox en el DataGridView atreves de código de programación en C#?.

    ResponderEliminar
  187. Buenas tardes, mi duda es: ¿Como inserto los datos seleccionados en la del combobox que esta dentro del datagrid? Osea, vincule los combobox a mi tabla de base de datos y salen pero ahora quiero que se guarden los que seleccione, como haria?

    ResponderEliminar
  188. Exelente ayuda mucho los aportes de los demas....tengo un problema de mi datagridView.....mmmm aver...... estamos importanto las tablas desde el postgreSql en el datagridView salen todos los datos con una consulta sql lo q pasa es q no se visualizan a simple vista al momento de hacer click la fila si e ven q estan hay pero despues sale todo blanco........ademas al cambiar el color de la letra del datagridView solo se cambian filas intercaladas......help...help....como puedo arreglar eso

    ResponderEliminar
  189. buenas tardes muy buenos tus aportes y gracias por ello, por favor permítame hacerle una consulta y de seguro podrá ayudarme:
    tengo un textbox y un dataGrid, como puedo hacer para que el focus se quede en el textbox mientras recorro la grid?
    le explico lo siguiente: estoy realizando un sistema de ventas en el cual, en un textbox busco el producto y en el datagrid se enlista todo lo relacionado al producto y mientras recorro la tabla quiero que el focus se mantenga el textbox para poder escribir rápidamente otro producto...
    de antemano agradezco su ayuda gracias...

    ResponderEliminar
  190. buenos días,
    estoy intentando publicar un duda en los foros de msdn y no me deja acceder.
    no se si podras ayudarme.
    tengo una columna datagridviewcomboboxcolumn ligada aun datatable pero quiero que me deje insertar datos que no esten en el datasource para que me de opcion de lanzar un form para crearlo
    gracias

    Arantza

    ResponderEliminar