domingo, 1 de diciembre de 2013

Pasar datos de un DataGridView a otro DataGridView ubicados en Forms diferentes

Hola a todos:

Motivado por uno de los usuarios del Foro de C# me tomo unos minutos parar mostrar como podemos fácilmente enviar valores de un DataGridView a otro DataGridView ubicado en un formulario diferente.
Como siempre pondré el código tanto para C# como para Vb.Net, y tratare de ser los mas explicito posible, si después de leer el articulo, descargar el proyecto de ejemplo y analizar su contenido usted no logra implementarlo, sírvase de hacer las consultas que crea necesarias proporcionando la mayor cantidad de información de su caso.

Recuerde que el objetivo del articulo no es otro mas que el de proporcionar una guía para lo Párvulos en .Net y que solo es una opción para la solución de un problema, recordando que un problema tiene muchas posibles soluciones.

Recuerde que al final de Articulo podrá encontrar los proyectos de ejemplo descargables tanto para C# y Vb.Net.

Entrando en contexto…

Crearemos un proyecto que simulara la carga de artículos de un Formulario a otro Formulario utilizando controles DataGridView para mostrar los datos.
  1. El proyecto arrancara con el Form1 como principal
  2. Al presionar el botón “Agregar” se mostrara el Form2 con un control DataGridView cargado con datos
  3. Al hacer doble Click sobre algún row del DataGridView del Form2 automáticamente se enviara la información contenida en sus celdas al DataGridView del form1, mostrándose también en los controles TextBox.
  4. El proceso antes de agregar el nuevo Row al DataGridView hará una validación sobre los datos ya agregados para descartar que este articulo no se encuentre ya en la lista, de ser así lanzara una mensaje de informando de la situación y no agregara el row, en caso contrario el row será agregado sin problemas.
Dicho todo lo anterior, procedamos a crear nuestro proyecto de ejemplo.
  1. Cree un proyecto del tipo WindowsForms
  2. Automáticamente le creo un formulario llamado Form1, dejemos el nombre de los controles por defecto para no complicarnos la vida nombrándolos en estos momentos, aunque recalco que en proyecto reales el nombre de los controles es vital.
  3. Agregue 4 controles labels y establezca en la propiedad Text, Número, Nombre, Precio y Cantidad respectivamente
  4. Agregue 4 controles TextBox
  5. Agregue un control Button y establezca en la propiedad Text, Cargar.
  6. Agregue un control DataGridView, agregue 4 columnas, establezca la propiedad SelectionMode en FullRowSelect, AllowUserToAddRows, AllowUserToDeleteRows en false
Su diseño podría ser similar a este:
frm1

Ahora, en el Form dos inserte un control DataGridView similar al que acaba de crear en el Form1, para optimizar el tiempo puede copiar y pegar el control del Form1, el diseño que se espera obtenga es similar a este:
frm2
Bien, una vez que tengamos el tema del diseño de nuestros Forms resueltos, procedamos a meter código.
Inserte una nueva clase a su proyecto y llámela EProducto, la clase tendrá una estructura como esta:
C# :
using System;

namespace DataGridViewsendRow
{
    public class EProducto
    {
        //Estas son propiedades Autoimplementadas y su uso requiere
        // del Framework 4.0 Client Profile como mínimo
        public int Numero { get; set; }
        public string Nombre { get; set; }
        public Decimal Precio { get; set; }
        public Decimal Cantidad { get; set; }
    }
}

Vb.Net :
Public Class EProducto
    'Estas son propiedades Autoimplementadas y su uso requiere
    'del Framework 4.0 Client Profile como mínimo
    Public Property Numero() As Integer
    Public Property Nombre() As String
    Public Property Precio() As Decimal
    Public Property Cantidad() As Decimal
End Class

Agregue una nueva clase y llámela IProducto, esta clase contendrá una interfaz que será el puente de comunicación entre ambos Forms, este es el Core de nuestro proyecto y ejemplo.

Dentro de la clase cree la siguiente estructura de código:

C# :
namespace DataGridViewsendRow
{
    //Nombre de la interfaz
    public interface IProducto
    {
        bool LoadDataRow(EProducto producto);
    }
}

Vb.Net :
'Nombre de la interfazPublic Interface IProducto
    Function LoadDataRow(producto As EProducto) As Boolean
End Interface

Esta es la estructura completa de código que necesitara para recibir los datos en el Form1:

C# :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace DataGridViewsendRow
{
    //
    //Heredamos la Interfaz IProducto, recuerde que este será nuestro puente de comunicación entre ambos Forms
    public partial class Form1 : Form, IProducto
    {
        //
        //Creamos una lista del tipo Eproducto, que será la encargada de
        //recibir la información del Form2 y almacenarla, posteriormente servirá
        //de fuente de datos para el DataGridView
        private static readonly List<EProducto> Products = new List<EProducto>();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //
            //Instanciamos el Form2
            Form2 frm = new Form2();
            //
            //Le indicamos quien lo mando a llamar usando la Propiedad Caller
            frm.Caller = this;
            //
            //Mostramos el Form2
            frm.ShowDialog();
        }

        /// <summary>
        /// Funcion encargada de agregar un nuevo Item a la lista siempre y cuando no exista
        /// </summary>
        /// <param name="product">instancia de la clase Eproduct</param>
        /// <returns>Si el Item fue agregado a la lista devuelve True si no fue agregado retorna False</returns>
        public bool LoadDataRow(EProducto product)
        {
            //Busca si el Articulo ya se encuentra en la lista
            bool exists = Products.Any(x => x.Numero.Equals(product.Numero));
            //
            //
            //Preguntamos por el resultado de la búsqueda del Articulo dentro de la lista
            if (!exists)
            {
                //
                //Si el articulo no existe dentro de la lista Mapeamos el item de la entidad Eproducto 
                //a los TextBox
                textBox1.Text = Convert.ToString(product.Numero);
                textBox2.Text = product.Nombre;
                textBox3.Text = Convert.ToString(product.Precio);
                textBox4.Text = Convert.ToString(product.Cantidad);
                //
                //Agregamos a la lista de productos el Item enviado por el Form2
                //
                Products.Add(product);
                //
                //
                //
                dataGridView1.AutoGenerateColumns = false;
                //
                //
                dataGridView1.DataSource = null;
                //
                //Establecemos el DataSource del DataGridView enlazándolo a la lista
                //genérica
                dataGridView1.DataSource = Products;
                //
                //Mapeamos las propiedades a las columnas
                dataGridView1.Columns["ColumnNumero"].DataPropertyName = "Numero";
                dataGridView1.Columns["ColumnNombre"].DataPropertyName = "Nombre";
                dataGridView1.Columns["ColumnPrecio"].DataPropertyName = "Precio";
                dataGridView1.Columns["ColumnCantidad"].DataPropertyName = "Cantidad";

                //
                //Retornamos True
                return true;
            }
            //
            //Si la condición exists es igual a False, es decir, que el producto SI existe en la lista
            //retornamos FALSE para mostrar un mensaje información
            return false;
        }
    }
}

Vb.Net :
Public Class Form1
    '
    'Heredamos la Interfaz IProducto, recuerde que este será nuestro puente de comunicación entre ambos Forms
    Implements IProducto

    'Creamos una lista del tipo Eproducto, que será la encargada de
    'recibir la información del Form2 y almacenarla, posteriormente servirá
    'de fuente de datos para el DataGridView
    Private Shared ReadOnly Products As New List(Of EProducto)()

    Private Sub button1_Click(sender As System.Object, e As System.EventArgs) Handles button1.Click
        '
        'Instanciamos el Form2
        Dim frm As New Form2()
        '
        'Le indicamos quien lo mando a llamar usando la Propiedad Caller
        frm.Caller = Me
        '
        'Mostramos el Form2
        frm.ShowDialog()
    End Sub

    ''' <summary>
    ''' Funcion encargada de agregar un nuevo Item a la lista siempre y cuando no exista
    ''' </summary>
    ''' <param name="product">instancia de la clase Eproduct</param>
    ''' <returns>Si el Item fue agregado a la lista devuelve True si no fue agregado retorna False</returns>
    Public Function LoadDataRow(product As EProducto) As Boolean Implements IProducto.LoadDataRow

        'Busca si el Articulo ya se encuentra en la lista
        Dim exists As Boolean = Products.Any(Function(x) x.Numero.Equals(product.Numero))
        '
        '
        'Preguntamos por el resultado de la búsqueda del Articulo dentro de la lista
        If Not exists Then
            '
            'Si el articulo no existe dentro de la lista Mapeamos el item de la entidad Eproducto 
            'a los TextBox
            textBox1.Text = Convert.ToString(product.Numero)
            textBox2.Text = product.Nombre
            textBox3.Text = Convert.ToString(product.Precio)
            textBox4.Text = Convert.ToString(product.Cantidad)
            '
            'Agregamos a la lista de productos el Item enviado por el Form2
            '
            Products.Add(product)
            '
            '
            '
            dataGridView1.AutoGenerateColumns = False
            '
            '
            dataGridView1.DataSource = Nothing
            '
            'Establecemos el DataSource del DataGridView enlazándolo a la lista
            'genérica
            dataGridView1.DataSource = Products
            '
            'Mapeamos las propiedades a las columnas
            dataGridView1.Columns("ColumnNumero").DataPropertyName = "Numero"
            dataGridView1.Columns("ColumnNombre").DataPropertyName = "Nombre"
            dataGridView1.Columns("ColumnPrecio").DataPropertyName = "Precio"
            dataGridView1.Columns("ColumnCantidad").DataPropertyName = "Cantidad"

            '
            'Retornamos True
            Return True
        End If
        '
        'Si la condición exists es igual a False, es decir, que el producto SI existe en la lista
        'retornamos FALSE para mostrar un mensaje información
        Return False
    End Function
End Class

Bien, ya tenemos la codificación del Form1, recuerde que este es el que hereda de la Interfaz, ahora vayamos a ver la codificación del Form2 encargado de enviar los datos del Row seleccionado:

C# :
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace DataGridViewsendRow
{
    public partial class Form2 : Form
    {
        //
        //Creamos una instancia de la interfaz IProducto para establecer el formulario llamador
        public IProducto Caller { private get; set; }

        public Form2()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Funcion encargada de devolver una lista de la Entidad EProducto cargada con datos
        /// </summary>
        /// <returns>Lista genérica de Eproucto</returns>
        private static List<EProducto> Products()
        {
            //Creamos la lista de Eproducto
            //
            List<EProducto> products = new List<EProducto>();

            //
            //Instanciamos la clase EProducto para establecerle datos
            //
            EProducto item1 = new EProducto()
            {
                Numero = 1,
                Nombre = "Nombre del producto 1",
                Precio = new decimal(5.5),
                Cantidad = new decimal(6.3)
            };
            EProducto item2 = new EProducto()
            {
                Numero = 2,
                Nombre = "Nombre del producto 2",
                Precio = new decimal(15.5),
                Cantidad = new decimal(2)
            };
            EProducto item3 = new EProducto()
            {
                Numero = 3,
                Nombre = "Nombre del producto 3",
                Precio = new decimal(25),
                Cantidad = new decimal(5)
            };
            EProducto item4 = new EProducto()
            {
                Numero = 4,
                Nombre = "Nombre del producto 4",
                Precio = new decimal(150.5),
                Cantidad = new decimal(12)
            };
            EProducto item5 = new EProducto()
            {
                Numero = 5,
                Nombre = "Nombre del producto 5",
                Precio = new decimal(4.5),
                Cantidad = new decimal(3)
            };
            EProducto item6 = new EProducto()
            {
                Numero = 6,
                Nombre = "Nombre del producto 6",
                Precio = new decimal(5),
                Cantidad = new decimal(6)
            };
            //
            //Agregamos las instancias con datos de Eproducto a la lista del mismo tipo
            //
            products.Add(item1);
            products.Add(item2);
            products.Add(item3);
            products.Add(item4);
            products.Add(item5);
            products.Add(item6);

            //
            //Devolvemos la lista
            //
            return products;
        }

        /// <summary>
        /// Método encargado de poblar el DatagridView con datos de una lista genérica, en este caso
        /// la devuelta por la función Products() creada previamente,
        /// </summary>
        private void FillDgv()
        {
            //Evitamos generar nuevas columnas a la izquierda de las que creamos en tiempo de diseño
            //
            dataGridView1.AutoGenerateColumns = false;
            //
            //Establecemos la fuente de datos, observe que únicamente mandamos a llamar a la función
            dataGridView1.DataSource = Products();
            //
            //Mapeamos las propiedades de la clase Eproducto devuelta por la función
            //Products() a las columnas del DataGridView
            //
            dataGridView1.Columns["ColumnNumero"].DataPropertyName = "Numero";
            dataGridView1.Columns["ColumnNombre"].DataPropertyName = "Nombre";
            dataGridView1.Columns["ColumnPrecio"].DataPropertyName = "Precio";
            dataGridView1.Columns["ColumnCantidad"].DataPropertyName = "Cantidad";

        }

        private void Form2_Load(object sender, EventArgs e)
        {
            //
             //Usamos el evento Load del Form2 para mostrar el DataGridView con datos
            FillDgv();
        }

        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                //
                //Si el row en el que hicimos doble click es el encabezado del DataGridView, nos retornamos.
                if (e.RowIndex == -1)
                    return;

                //
                //Obtenemos el row en el cual se hizo doble Click
                //
                DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

                //Instanciamos la clase Eproducto para cargar los datos tomándolos de las celdas del row
                EProducto item = new EProducto
                {
                    //
                    //Recuerde convertir al tipo de dato correcto
                    //
                    Numero = Convert.ToInt32(row.Cells["ColumnNumero"].Value),
                    Nombre = Convert.ToString(row.Cells["ColumnNombre"].Value),
                    Precio = Convert.ToDecimal(row.Cells["ColumnPrecio"].Value),
                    Cantidad = Convert.ToDecimal(row.Cells["ColumnCantidad"].Value)
                };

                //
                //Si no existe llamador para nuestro formulario nos retornamos sin hacer ninguna acción
                //
                if (Caller == null)
                    return;

                //Si el Form1 devolvió false por haber encontrado el Producto dentro de la lista
                //Informamos de lo sucedido al usuario
                if (!Caller.LoadDataRow(item))
                {
                    MessageBox.Show("El Producto ya existe en la lista", "Atención", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("Error : {0}", ex.Message), "Error Inesperado", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

Vb.Net :
Public Class Form2
    '
    'Creamos una instancia de la interfaz IProducto para establecer el formulario llamador
    Public Property Caller() As IProducto


    ''' <summary>
    ''' Función encargada de devolver una lista de la Entidad EProducto cargada con datos
    ''' </summary>
    ''' <returns>Lista genérica de Eproucto</returns>
    Private Shared Function Products() As List(Of EProducto)
        'Creamos la lista de Eproducto
        '
        Dim _products As New List(Of EProducto)()

        '
        'Instanciamos la clase EProducto para establecerle datos
        '
        Dim item1 As New EProducto()
        item1.Numero = 1
        item1.Nombre = "Nombre del producto 1"
        item1.Precio = New Decimal(5.5)
        item1.Cantidad = New Decimal(6.3)

        Dim item2 As New EProducto()
        item2.Numero = 2
        item2.Nombre = "Nombre del producto 2"
        item2.Precio = New Decimal(15.5)
        item2.Cantidad = New Decimal(2)

        Dim item3 As New EProducto()
        item3.Numero = 3
        item3.Nombre = "Nombre del producto 3"
        item3.Precio = New Decimal(25)
        item3.Cantidad = New Decimal(5)

        Dim item4 As New EProducto()
        item4.Numero = 4
        item4.Nombre = "Nombre del producto 4"
        item4.Precio = New Decimal(150.5)
        item4.Cantidad = New Decimal(12)

        Dim item5 As New EProducto()
        item5.Numero = 5
        item5.Nombre = "Nombre del producto 5"
        item5.Precio = New Decimal(4.5)
        item5.Cantidad = New Decimal(3)

        Dim item6 As New EProducto()
        item6.Numero = 6
        item6.Nombre = "Nombre del producto 6"
        item6.Precio = New Decimal(5)
        item6.Cantidad = New Decimal(6)

        '
        'Agregamos las instancias con datos de Eproducto a la lista del mismo tipo
        '
        _products.Add(item1)
        _products.Add(item2)
        _products.Add(item3)
        _products.Add(item4)
        _products.Add(item5)
        _products.Add(item6)

        '
        'Devolvemos la lista
        '
        Return _products
    End Function

    ''' <summary>
    ''' Método encargado de poblar el DatagridView con datos de una lista genérica, en este caso
    ''' la devuelta por la función Products() creada previamente,
    ''' </summary>
    Private Sub FillDgv()
        'Evitamos generar nuevas columnas a la izquierda de las que creamos en tiempo de diseño
        '
        dataGridView1.AutoGenerateColumns = False
        '
        'Establecemos la fuente de datos, observe que únicamente mandamos a llamar a la función
        dataGridView1.DataSource = Products()
        '
        'Mapeamos las propiedades de la clase Eproducto devuelta por la función
        'Products() a las columnas del DataGridView
        '
        dataGridView1.Columns("ColumnNumero").DataPropertyName = "Numero"
        dataGridView1.Columns("ColumnNombre").DataPropertyName = "Nombre"
        dataGridView1.Columns("ColumnPrecio").DataPropertyName = "Precio"
        dataGridView1.Columns("ColumnCantidad").DataPropertyName = "Cantidad"

    End Sub

    Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        FillDgv()
    End Sub

    Private Sub dataGridView1_CellDoubleClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dataGridView1.CellDoubleClick
        Try
            '
            'Si el row en el que hicimos doble click es el encabezado del DataGridView, nos retornamos.
            If e.RowIndex = -1 Then
                Return
            End If

            '
            'Obtenemos el row en el cual se hizo doble Click
            '
            Dim row As DataGridViewRow = dataGridView1.Rows(e.RowIndex)

            'Instanciamos la clase Eproducto para cargar los datos tomándolos de las celdas del row
            '
            'Recuerde convertir al tipo de dato correcto
            '
            Dim item As New EProducto()
            item.Numero = Convert.ToInt32(row.Cells("ColumnNumero").Value)
            item.Nombre = Convert.ToString(row.Cells("ColumnNombre").Value)
            item.Precio = Convert.ToDecimal(row.Cells("ColumnPrecio").Value)
            item.Cantidad = Convert.ToDecimal(row.Cells("ColumnCantidad").Value)

            '
            'Si no existe llamador para nuestro formulario nos retornamos sin hacer ninguna acción
            '
            If Caller Is Nothing Then
                Return
            End If

            'Si el Form1 devolvió false por haber encontrado el Producto dentro de la lista
            'Informamos de lo sucedido al usuario
            If Not Caller.LoadDataRow(item) Then
                MessageBox.Show("El Producto ya existe en la lista", "Atención", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            End If
        Catch ex As Exception
            MessageBox.Show(String.Format("Error : {0}", ex.Message), "Error Inesperado", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub
End Class

Hasta este momento hemos creado nuestro diseño, nuestra clase entidad, la interfaz y nuestro estructura de código interno, ¿Que nos falta?, pues únicamente probar nuestro proyecto de ejemplo:
Presione F5 para realizar las pruebas.
Presione el botón “Agregar”
Si realizo las cosas de acuerdo a las instrucciones, podrá ver el DataGridView del Form2 poblado con datos:
frm3
Haga doble Click sobre cualquier Row del datagridView para enviar los datos al Form1: 
frm4
 Ahora haga doble Click sobre un Producto ya enviado previamente:
frm5
 Bueno hemos llegado al final del articulo, si siguió el articulo completo no tendrá problemas para la implementación y adaptación de este ejemplo en sus proyecto de desarrollo.
Saludos desde Monterrey, Nuevo León México!

Ejemplo C#
Ejemplo Vb.Net
Nota: El proyecto fue desarrollado en Vs2010 Ultímate usando Framework 4.0 Client Profile

32 comentarios:

  1. te hago una consulta, probe el codigo y me sirvio para un proyecto que estoy haciendo, si quisiera eliminar como tendria que hacer?, como podria usar el mismo codigo para eliminar, gracias y saludos

    ResponderEliminar
  2. Hola:
    Antes que otra cosa agradezco tu comentario, con respecto a tu pregunta, no entiendo completamente el escenario que planteas, podrías extender tu explicación por favor.

    Saludos desde Monterrey, Nuevo León, México

    ResponderEliminar
  3. hola de nuevo jose luis, yo necesitaba agregar ciertos datos a una lista pasandolos de un datragridview en un form a otro datagridview en otro form, con tu codigo lo consegui, solo tuve que cambiar las listas, ahora el problema es que tambien quiero eliminar los datos que esten en un datagridview en un formulario haciendo dobleclick en en datagridview del formulario hijo, lo intente de varias maneras pero hasta ahora no lo consegui, gracias de nuevo

    ResponderEliminar
  4. Ah! ok ya entiendo, pero otra pregunta, el DataGridView del cual deseas eliminar el registro esta enlazado a una fuente de datos? o agregaste las filas usando el Add del control?, bueno fuera cual fuera, te explico a grades rasgos lo que yo haría:

    1.-En el ejemplo se muestra como enviar el Id del registro
    Si esta enlazado:

    //Busco en la lista si existe el valor de Id recibido:
    bool exists = _lista.Any(x => x.NombrePropiedad.Equals(Convert.ToInt32(Id)));
    //Si existe
    if(exists)
    {
    //remuevo el item de la lista usando el RemoveAt(indice)
    }

    Si no esta enlazo:
    Recorro la colección de rows del control y cuando encuentre el Id utilizo el Remove

    Listo!!

    ResponderEliminar
  5. yo tengo una problema que me esta volviendo loco, estoy haciendo un proyecto para comparar y pasar los datos de 2 datagridview a otro tercero pero no he podido he visto ya varias sintaxis pero el datagridview al que quiero que se pasen los datos no se muestra(por cierto el tercero no está conectado a ninguna bd ni tabla

    ResponderEliminar
    Respuestas
    1. Hola abner:
      Pero como es que quieres validar estos dos DGV, osea los registros tienen algun campo en comun o quieres validar todas las columnas de ambos DGV para luego obtener los coincidentes y volcarlos al tercer DGV?

      Eliminar
  6. Me ayudo tu articulo, felicitaciones!!! José Luis, buen aporte.

    ResponderEliminar
    Respuestas
    1. Hola Pedro:
      Me da gusto que el artículo haya sido de utilidad a tus propósitos...

      Saludos desde Monterrey, Nuevo León, México

      Eliminar
  7. muchas gracias por tu post, felicidades me ayudo en mi proyecto,,,,
    me gustaria hacerle una consulta y haber si me ayudas a solucionar mi trauma jaja....
    lo que pasa es que tengo un formVenta y en el un datagridview donde estan los datos de los productos.., cuando hago click sobre cualquier fila, me aparece un nuevo form (formCantidad) con los datos del producto seleccionado para ingresar la cantidad que deseo, hasta ahi todo bien.....(aqui su ayuda)
    lo que necesito es una vez ingresada la cantidad requerido del producto, al presionar boton agregar, se me agreguen los datos del producto del formCantidad a otro datadrigview del formPedidos, para luego agregar o eliminar el pedido a la base de datos...(ojo se podra agregar el pedido cuando hacemos click en el btn_agregarPedido)

    ResponderEliminar
    Respuestas
    1. me equivoco que en ojo jajaja
      decia que solo se podra agregar a la base de datos si se hizo click en el btn_agregar_pedidos
      mientras no se hace click en el boton agregar.....solo se puede cancelar, eliminar o remplazar el producto sin que éste aun no se ingrese a la bd... gracias de antemano

      Eliminar
  8. Como copio datos de Un dataGridView1 a dataGridView2 pero en C++ y en en mismo Form?
    Muchas Gracias...

    ResponderEliminar
    Respuestas
    1. Hola Allan:
      Lamento decirte que dentro de mis conocimientos no se encuentra el lenguaje de programación C++ (al menos no por ahora)...

      Saludos desde Monterrey, Nuevo León, México

      Eliminar
  9. Muchas felicdades. Muy buen articulo. Quisiera ver si me podrias ayudar con una consulta. Como le hago para que cuando se agregue un registro al datagridview del form1, se me genere una fila en blanco. Ya que yo mando llamar el form2 desde el datagridview y cuando el form2 me envia los datos al datagridview del form1 cierro el form2 y ya no puedo seguir agregando registros.

    No se si me logre explicar. Espero me puedas ayudar.

    Saludos

    ResponderEliminar
    Respuestas
    1. Hola Frank:

      Cuando dices que no puedes seguir agregando registros es porque recibes algún mensaje de error?, como es que estas agregando registros a tu control DataGridView es por medio del Add() o por medio del DataSource, porque usar esta técnica no interfiere en nada en la adición de nuevos registros al control.

      Espero tus comentarios

      Saludos

      Eliminar
  10. Hola Buen dia.

    Los registros los agrego por medio del DataSource. No me manda ningun error. Al agregar un registro que seleccione del form2, me regreso al from1 y el registro me lo agrega bien, pero como te comente, yo mando llamar el form2 desde un boton dibujado dentro de la celda datagridview, y para agregar mas registros necesito una nueva fila en blanco para poder llamar nuevamente al form2.

    Saludos

    ResponderEliminar
    Respuestas
    1. Hola:

      Y de casualidad tienes habilitado la opción "AllowUserToAddRows" si no es así por favor habilitala, esta propiedad genera un nuevo registro en blanco automaticamente después de que el usuario crea uno.

      Saludos

      Eliminar
  11. Muy buen Articulo, felicidades... Una consulta supongamos que los datos que me arroja el DataGridView del form2 no los quiero generar directamente como tu los haces, sino que estos datos los tengo en una base de datos. Como hacer para enviarlos al Form1?

    ResponderEliminar
    Respuestas
    1. Hola: ¿Entonces que es lo que muestras en el datagridview del form2? Si muestras el idioma entonces este es lo que mandarias al form1 y cuando llegue allá recuperas el resto de campos de la bd. Sin más detalles es lo que puedo decir.

      Saludos

      Eliminar
    2. En el datagridview del form2 deseo mostrar los productos (una venta) que tengo almacenados en mi BD lo cual los cargo en el dgv del form1. Espero ser explicito y puedas ayudarme.

      Eliminar
  12. Hola:
    pero cuando dices productos ¿a que te refieresu una entidad producto podría tener muchas propiedades.

    Bueno supongo que la descripción del producto, si es así entonces regresa esto y que la interfaz tenga una función que regrese el resto de propiedades de la entidad, está interfaz la implementas en presentacion.

    O bien puedes usar algo como lo que sugiero en un artículo de este mismo blog, no recuerdo el nombre exacto pero es autocomplete texrbox parte 2

    ResponderEliminar
    Respuestas
    1. Hola:
      Entrando en detalles, mi form1 es un formulario de ventas, mi form2 es un formulario de productos(id, Descripcion, Precio etc). Lo que deseo hacer es que al realizar una venta llamar al formulario de productos y seleccionar "x" productos y enviarlos al DataGridView del formulario ventas.
      Pero como explicaba antes el formulario productos lo cargo con datos de una BD

      Eliminar
    2. El datagridview del formulario producto tiene como columnas idProducto, Descripcion y Precio al igual que el dgv del formulario ventas.

      Saludos

      Eliminar
    3. Hola: has lo que sugiero envía únicamente el id y que el void deI form1 sea quien se encargue de hacer la búsqueda.

      Eliminar
  13. Hola:
    Me sirvió de mucho este post, gracias de antemano, pero tengo una consulta, al cerrar el form de compra donde se encuentra el DGV padre o principal todo Ok, registra sin ningun problema, pero al volver abrirlo el form Compra, el DGV aparece en blanco hasta ahi Ok, pero al agregar un articulo, me vuelve a aparecer los articulos agregados antes de cerrar el form, o sino sale producto ya existe, ojala pueda ayudarme en este caso.

    ResponderEliminar
    Respuestas
    1. Hola:
      Pues eso dependerá de como es que estés creando la instancia de la lista genérica que contiene los datos, osea, si creas una instancia Static pues esta siempre se mantendrá, también depende como es que estés mandando a llamar al formulario.

      Recuerda que cuando desees llamar aun formulario tienes que hacer una instancia de la clase por ejemplo:

      private void bntnCompras_click(...)
      {
      FormCompra frm = new FormCompra();
      frm.Show();
      }

      De esa forma cada vez que tu hagas clic sobre el botón se creara una nueva instancia del formulario Compra y por ende todos los objetos que contiene se crearan desde cero.

      Saludos

      Eliminar
  14. Hola Jose Luis Buen dia.

    Me podrias ayudar para que cuando en el datagridview ya exista un ID, al querer agregar el mismo ID no me envie el mensaje, si no que me aumente la cantidad en uno mas.

    Este es el codigo que tengo

    Sub InsertarProducto() 'Procedimieto para insertar la linea del producto a poner en el datagridview
    Try
    Dim rows As DataRow() = BuscarId(TextBox1.Text) ' Obtenemos el array de objetos DataRow
    If (rows.Length = 0) Then Return ' Si no hay ninguna línea abandonamos el procedimiento.
    Dim dt As DataTable = DirectCast(DataGridView1.DataSource, DataTable) ' Referenciamos el objeto DataTable enlazado con el control DataGridView
    For Each linea As DataRow In rows ' recuperados de la consulta.
    dt.ImportRow(linea) ' Importamos al objeto DataTable las nuevas filas u objetos DataRow
    Next
    DataGridView1.CurrentCell = DataGridView1.Rows(dt.Rows.Count - 1).Cells("Cantidad") ' Nos posicionamos en la primera celda de la fila del datagridview
    DataGridView1.CurrentRow.Cells("Cantidad").Value = 1
    Catch ex As Exception
    ' Se ha producido un error
    MessageBox.Show(ex.Message)
    End Try
    TextBox1.Text = ""
    TextBox1.Focus()
    End Sub

    'Funcion que devuelve el row con los datos del articulo
    Private Function BuscarId(ByVal Id As String) As DataRow()
    Using cnn As New SqlConnection("Data Source=.;Initial Catalog=FACTURACION;Integrated Security=True")
    Dim cmd As SqlCommand = cnn.CreateCommand()
    cmd.CommandText = "SELECT IdProducto, Descripcion, Precio FROM Productos WHERE Idproducto = @Id "
    cmd.Parameters.AddWithValue("@Id", Id)
    Dim _da As New SqlDataAdapter(cmd)
    Dim _dt As New DataTable("Productos")
    _da.Fill(_dt)
    Dim _Rows(_dt.Rows.Count - 1) As DataRow ' Creamos la matriz.
    If _Rows.Count = 0 Then 'Validamos si el Id en la base de datos
    MessageBox.Show("Articulo no existe en la base de datos")
    TextBox1.Clear()
    TextBox1.Focus()
    Else
    _dt.Rows.CopyTo(_Rows, 0) ' Copiamos las filas a la matriz creada.
    End If
    Return _Rows ' Devolvemos la matriz.
    End Using
    End Function

    Lo llamo desde el evento keypress de un textbox

    Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
    If e.KeyChar = Convert.ToChar(Keys.Enter) Then
    AddHandler DataGridView1.CellValueChanged, AddressOf CalcularCelda 'Para calcular la columna Importe
    InsertarProducto()


    End If
    Sum()
    End Sub

    los ID los inserto desde un textbox que realiza la consulta mediante los procedimientos y los inserta en el datagridview

    ResponderEliminar
  15. Buen Día.

    Jose Luis

    podrias volver a subir el link de descarga del proyecto que quiero probarlo e implementar algo similar. de ante mano muchas gracias


    Elías Cáceres, Stgo de Chile.

    ResponderEliminar
  16. Ya no funciona el vinculo podrias volverlo a subir porfavor

    ResponderEliminar
  17. Hola amigo tengo una problema cuando llamo a la clase esta me tira error podrias volver a subir el archivo

    ResponderEliminar
  18. Buen trabajo me ha servido mucho.... gracias por compartir tus conocimientos con principiantes como yo tengo una duda estoy haciendo un programa super complicado estoy trabando con arreglos, los arreglos deben almacenar los datos introduccidos por el usuario tengo almacenar el nombre calcular descuentos del salario que son como 5 descuentos y posterior esos resultados mostrarlos escritos por el usuario mostrarlo en un data grid y no se como almacenar los datos que introduzca el usuario que aparezcan en el data grid el programa solo pide el nombre y el salario lo demas debe ser codificado y posterior imprimido en un data grid espero con ansias tu ayuda .

    ResponderEliminar










  19. Hola que tal!!
    Gracias por ayudarnos, pero tengo una consulta.Porque al momento de crear estos terminos similares al tuyo aparece un error
    -frm.Caller = this;
    -bool exists = Products.Any(x => x.Numero.Equals(product.Numero));

    No me aceptan los terminos me dice que genere una propiedad aparte aun, porfavor ayudame a resolver este problema!
    -(!Caller.LoadDataRow(item))

    ResponderEliminar

Deja un comentario si el articulo fue de utilidad.