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

 

Aquí puede seleccionarse dos opciones:

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

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

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:

 

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

 

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.

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]

174 comentarios:

ATP dijo...

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.

Leandro Tuttini dijo...

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

ATP dijo...

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.

Leandro Tuttini dijo...

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

Jonathan Ulises dijo...

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(

Leandro Tuttini dijo...

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

Jonathan Ulises dijo...

*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.

Leandro Tuttini dijo...

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

Fernando S. dijo...

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

Fernando S. dijo...

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

Leandro Tuttini dijo...

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

Leandro Tuttini dijo...

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

mijares dijo...

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

Leandro Tuttini dijo...

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

Anónimo dijo...

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%';

Leandro Tuttini dijo...

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

leandro dijo...

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

Leandro Tuttini dijo...

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

Tania Malfoy dijo...

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 ;).

Leandro Tuttini dijo...

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

Tania Malfoy dijo...

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 ;)!!!

Luis dijo...

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

Leandro Tuttini dijo...

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

Anita dijo...

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

Leandro Tuttini dijo...

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

Conchi dijo...

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

Leandro Tuttini dijo...

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

Conchi dijo...

Muchísimas gracias Leandro.

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

Saludos,
Conchi

Conchi dijo...

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

Leandro Tuttini dijo...

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

Conchi dijo...

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

Leandro Tuttini dijo...

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

Pierina Joplin dijo...

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!!

Leandro Tuttini dijo...

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

Pierina Joplin dijo...

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...

Leandro Tuttini dijo...

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

Conchi dijo...

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

Leandro Tuttini dijo...

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

Conchi dijo...

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

Conchi dijo...

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

Leandro Tuttini dijo...

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

reynaldo dijo...

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......

preiles dijo...

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

Leandro Tuttini dijo...

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

David Andres Hoyos Rondon dijo...

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.

Leandro Tuttini dijo...

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

JONA dijo...

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

Leandro Tuttini dijo...

hola JONA

te refieres a algo como esto

ADO.NET – Parte 4 – Actualización Información Ms Access

saludos

Jonathan Muñoz Solano dijo...

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,

Leandro dijo...

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.

Leandro Tuttini dijo...

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

Leandro dijo...

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

Leandro Tuttini dijo...

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

Leandro dijo...

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";
}

Leandro Tuttini dijo...

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

Leandro dijo...

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".

Leandro Tuttini dijo...

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

Leandro dijo...

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

Leandro Tuttini dijo...

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

thedanie dijo...

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

Leandro Tuttini dijo...

hola thedanie

apuntas a algo como esto

[DataGridView] KeyPress detectar ENTER y búsqueda


saludos

Piloni dijo...

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.

Leandro Tuttini dijo...

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

Piloni dijo...

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

Leandro Tuttini dijo...

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

Santiago dijo...

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

Leandro Tuttini dijo...

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

Santiago dijo...

Hola Leandro

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

Santiago.

veronica dijo...

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

Leandro Tuttini dijo...

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

veronica dijo...

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

veronica dijo...

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

Leandro Tuttini dijo...

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

veronica dijo...

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.

veronica dijo...

saludos

Leandro Tuttini dijo...

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

veronica dijo...

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.

Leandro Tuttini dijo...

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

Fernando Uriel Jaramillo Ugalde dijo...

espero me puedas ayudar

Fernando Uriel Jaramillo Ugalde dijo...

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 :)

Leandro Tuttini dijo...

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

Fernando Uriel Jaramillo Ugalde dijo...

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

Fernando Uriel Jaramillo Ugalde dijo...

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

Leandro Tuttini dijo...

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

Fernando Uriel Jaramillo Ugalde dijo...

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 ?

Leandro Tuttini dijo...

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

Fernando Uriel Jaramillo Ugalde dijo...

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

Fernando Uriel Jaramillo Ugalde dijo...

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 .

Fernando Uriel Jaramillo Ugalde dijo...

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!

Leandro Tuttini dijo...

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

Carlos Almanzar dijo...



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.

Leandro Tuttini dijo...

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

Carlos Almanzar dijo...

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


Leandro Tuttini dijo...

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

Carlos Almanzar dijo...

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

Andres Martinez dijo...

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.

Andres Martinez dijo...

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

Leandro Tuttini dijo...

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

Ian Ross dijo...

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

saludos

Ian

Ian Ross dijo...

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

Leandro Tuttini dijo...

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

Deyvi Javier Saavedra Garcia dijo...

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

Leandro Tuttini dijo...

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

Deyvi Javier Saavedra Garcia dijo...

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

Deyvi Javier Saavedra Garcia dijo...

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

Leandro Tuttini dijo...

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

Deyvi Javier Saavedra Garcia dijo...

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

Claudio Fredes dijo...

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

Leandro Tuttini dijo...

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

Juan Francisco Mejia dijo...

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

Leandro Tuttini dijo...

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

Fer Nas dijo...

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

Leandro Tuttini dijo...

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

Fer Nas dijo...

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

Angie Mar dijo...

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

Leandro Tuttini dijo...

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

ivette rodriguez aguila dijo...

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!!!!

Leandro Tuttini dijo...

hola ivette

podrias definir el

EmptyDataTemplate

con eso defines un template cuando no hay datos

saludos

Pierre dijo...

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.

Leandro Tuttini dijo...

hola Pierre

aqui

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

planteo ese tema

saludos

Pierre dijo...

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.

Pierre dijo...

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

Pierre dijo...

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

Leandro Tuttini dijo...

hola Pierre

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

saludos

Pierre dijo...

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

Leandro Tuttini dijo...

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

Pierre dijo...

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

Pierre dijo...

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

Leandro Tuttini dijo...

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

Pierre dijo...

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'

Leandro Tuttini dijo...

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

Pierre dijo...

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.

Pierre dijo...

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


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

Pierre dijo...

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

Leandro Tuttini dijo...

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

Pierre dijo...

hola leandro

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

Leandro Tuttini dijo...

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

Pierre dijo...

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

Leandro Tuttini dijo...

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

Pierre dijo...

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.

Leandro Tuttini dijo...

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

gilberto reyes dijo...

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.

gilberto reyes dijo...

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.

Leandro Tuttini dijo...

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

gilberto reyes dijo...

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

gilberto reyes dijo...

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..

Leandro Tuttini dijo...

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

gilberto reyes dijo...

ok gracias leandro

Jose Giron dijo...

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



Jose Giron dijo...

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



Javier dijo...

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.

Leandro Tuttini dijo...

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

Jose Giron dijo...

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

Jose Giron dijo...

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

Leandro Tuttini dijo...

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

Jose Giron dijo...

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

Jose Giron dijo...

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

Leandro Tuttini dijo...

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

Andres Gustavo dijo...

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

Leandro Tuttini dijo...

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

Andres Gustavo dijo...

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?

Leandro Tuttini dijo...

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

Andres Gustavo dijo...
Este comentario ha sido eliminado por el autor.
Andres Gustavo dijo...
Este comentario ha sido eliminado por el autor.
Andres Gustavo dijo...

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

Jimmy Garcia Condega dijo...

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

Jimmy Garcia Condega dijo...

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

Leandro Tuttini dijo...

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

David Figueroa dijo...

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;

Leandro Tuttini dijo...

hola David

lo obtienes por medio del Value de la celda

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

saludos

Yohana Maribel Duchen dijo...

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

Leandro Tuttini dijo...

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

Abel Deltell dijo...

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 :)

Leandro Tuttini dijo...

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