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.
- El proyecto arrancara con el Form1 como principal
- Al presionar el botón “Agregar” se mostrara el Form2 con un control DataGridView cargado con datos
- 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.
- 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.
- Cree un proyecto del tipo WindowsForms
- 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.
- Agregue 4 controles labels y establezca en la propiedad Text, Número, Nombre, Precio y Cantidad respectivamente
- Agregue 4 controles TextBox
- Agregue un control Button y establezca en la propiedad Text, Cargar.
- Agregue un control DataGridView, agregue 4 columnas, establezca la propiedad SelectionMode en FullRowSelect, AllowUserToAddRows, AllowUserToDeleteRows en false

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:

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:

Haga doble Click sobre cualquier Row del datagridView para enviar los datos al Form1:

Ahora haga doble Click sobre un Producto ya enviado previamente:

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