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.
- 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.
Dicho todo lo anterior, procedamos a crear nuestro proyecto de ejemplo.
- 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
Su diseño podría ser similar a este:
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