Pasar Datos Entre Formularios C# WinForm

En esta entrega de HazloExpress cubriremos la necesidad de pasar datos entre formularios en C# con Windows Form o WinForm.

Por lo general pasamos datos desde un formulario a otro formulario al momento de llamarlo y lo hacemos haciendo uso del constructor de la clase de ese formulario o a través de algún método público que contenga.

¿Pero que pasa si queremos pasar datos desde un formulario ya abierto hacia el formulario que lo invocó?

Si estas leyendo este post, entonces es porque te habrás dado cuenta de que pareciera ser imposible. Y te puedo decir que, aunque parezca difícil o imposible, ¡no lo es!

Si Bien podrías usar variables estáticas y pasar la data, pero que pasa si tienes varias ventanas que necesitan esta operación, además de que es un derroche de recurso usar variables estáticas para estos fines.

Bien, ¿entonces cual es la forma correcta?

¡Interfaces!

Sí, con una interfaz podemos solucionar este problema, usando un principio de desarrollo orientado a objeto llamado inversión de dependencia.

Para esto crearemos un proyecto en visual studio y seleccionaremos como lenguaje de programacion a C# le llamaremos ComunicarFormularios.

En nuestro proyecto usaremos 2 formularios

Uno será llamado padre (Este será el que invoca, el que recibirá los datos)

El otro será llamado hijo (quien envía los datos)

También necesitaremos una Interface.

Esta será llamada IContract y solo contendrá un método llamado Ejecutar, (ojo, la interfaz se crean sin modificador de acceso, para este ejemplo se le aplicara el modificador de acceso public).

namespace ComunicarFormularios
{
    public interface IContract
    {
        void Ejecutar(string texto); 
    }
}

Ahora bien, la ventana o formulario llamado Padre tendrá los siguientes controles

Daremos doble clic en el botón y agregaremos el siguiente código

 Hijo hijo = new Hijo();
 hijo.contrato = this;
 hijo.Show();

También heredaremos de la interfaz Icontract e implementaremos su método el cual sobrescribiremos con el código siguiente.

 public void Ejecutar(string texto)
 {
    LblMensaje.Text = texto; //control label
 }

La clase padre quedaría de la siguiente forma

namespace ComunicarFormularios
{
    public partial class Padre : Form , IContract
    {
        public Padre()
        {
            InitializeComponent();
        }

        public void Ejecutar(string texto)
        {
            LblMensaje.Text = texto;
        }

        private void BtnLlamarHijo_Click(object sender, EventArgs e)
        {
            Hijo hijo = new Hijo();
            hijo.contrato = this;
            hijo.Show();
        }
    }
}

También puede que te interese Como filtrar datos en Datagridview C#

La ventana Hijo tendrá los siguientes controles

En este formulario iremos a la clase y agregaremos una propiedad de tipo Icontract la cual llamaremos contrato.

public IContract contrato { get; set; }

En el botón enviar mensaje daremos doble clic y agregaremos el siguiente código

private void BtnEnviar_Click(object sender, EventArgs e)
{
   contrato.Ejecutar(TxtMensaje.Text);
}

La clase quedaría de la siguiente forma

namespace ComunicarFormularios
{
    public partial class Hijo : Form
    {
        public IContract contrato { get; set; }

        public Hijo()
        {
            InitializeComponent();
        }

        private void BtnEnviar_Click(object sender, EventArgs e)
        {
            contrato.Ejecutar(TxtMensaje.Text);
        }
    }
}

Ahora ejecutaremos a la aplicación y obtendremos el siguiente resultado

Eso es todo!


Explicación

El formulario hijo no tiene el mecanismo para hacer referencia hacia el objeto que lo invocó, sin embargo cuando instanciamos el objeto hijo le asignamos a la propiedad contracto el valor this, este le pasa la referencia del objeto que lo está invocando o llamando.

//clase padre
Hijo hijo = new Hijo();
hijo.contrato = this; // paso de referencia
hijo.Show();

//Clase Hijo
public IContract contrato { get; set; }

La interfaz por su parte crea una especie de contrato entre ambos objetos, lo cual le permite al objeto hijo invocar los métodos que contiene la interfaz, pero desde la clase padre, ya que el objeto de tipo interfaz fue inicializado con la referencia de la clase padre.

Despues de todo no era tan dificil pasar datos entre formularios C# en WinForm , lo bueno de esto es que puedes utilizar este mecanismo para pasar datos entre objetos, no solo formularios, y mejor aun puedes utilizarlo en cualquier lenguaje de programacion orientado a objetos.


Espero que te sea de ayuda, dale me gusta y no te olvide de compartir y valorar este post.

5/5 - (11 votos)

28 pensamientos en “Pasar Datos Entre Formularios C# WinForm

  1. TSM_KRIS

    no me funciona tu codigo y eso que copie y pegue todo con los mismos nombres y toda la cosa pero me manda un error al crear la propiedad tipo IContract me dice que existe una incoherencia y manda el error CS0053 no se si me podrias ayudar con eso

    1. Aris Valdez

      Hola @TSM_KRIS, este error ‘CS0053’, es producido debido a que cuando creas una **interface**, por defecto se crea sin modificador de acceso.

      la solución es que en la interfaz IContract, le coloques el modificador public delante.

      public interface IContrac
      {

      }

    1. Aris Valdez

      Hola emerson, ese error se debe a que la clase que implementa la interfaz, tambien debe implementar los metodos, en este caso debes reescribir el metodo Ejecutar en la clase Padre

  2. Luis Edaurdo Frias

    me subraya la palabra contrato y me dice

    (codigo de error CS1061)

    C # ‘Formulario’ no contiene una definición y no se puede encontrar ningún método de extensión accesible que acepte un primer argumento de tipo ‘Formulario’ (¿falta una directiva de uso o una referencia de ensamblado?))

    1. Aris Valdez

      Hola Luis, tiene que crear una variable en la clase del formulario definido como el hijo, o el que es llamado, donde la variable debe ser del tipo de la interfaz.

      Gracias por comentar.

    1. Aris

      en el Código hay dos formularios y una interfaz,
      la variable contrato debe ir en la clase que devolverá los valores

  3. Marcos Restituyo

    Muy bien hecho, de hecho lo necesitaba para java y como son lenguajes muy parecidos lo entendí, muchas gracias man

    1. Aris

      si, lo que sucede es que visual studio crea las clases e interfaces sin modificador de acceso publico, tenemos que agregarselo nosotros.

      ya corregí esa parte en el tuto.

  4. Walther Salas Barron

    Gracias, me funciono a la perfeccion, aunque la verdad no logro entenderlo del todo. Ahora toca implementarlo en un proyecto que estoy haciendo.

    1. Aris

      Gracias por comentar.
      el funcionamiento esta fundamentado en el paso por valor y paso por referencias, para este caso como es un objeto se aplica lo de paso por referencias.

      Esto permite que puedas acceder a una propiedad y/o métodos de un objeto desde otra ubicación del código siempre y cuando sea publico o internal

    1. Aris

      puedes agregar otro método a la interfaz, pero según el principio de segregación de interfaces es mejor tener una interfaz por metodo.

      en tu caso seria una interfaz por comando (metodo).

  5. Ruben

    Buenas que tal.. estoy probando tu codigo entre 2 formularios, 1 es ventas y el otro es buscar clientes y me sale error en el boton de buscar clientes, dejo el codigo :
    private void btnBuscarCli_Click(object sender, EventArgs e)
    {
    frmBuscarCliente hijo = new frmBuscarCliente();
    hijo.contrato = this; // en el this me marca el error: Ya existe una coversion explicita….
    hijo.ShowDialog();

    1. Aris

      Saludos Ruben.
      al mirar tu codigo no puedo determinar el error.

      pero te puedo sugerir que verifiques 2 cosas:
      1 – La clase Venta debe implementar la interfaz IContract
      2 – La propiedad que se llama contrato la cual esta en la clase FrmBuscarCliente debe ser de tipo IContract

      espero puedas resolver el error y esto te sea de ayuda

  6. luis

    hola a mi me da un error que se refiere a que el objeto de la interface esta nulo y no hace nada y bueno últimamente esos errores de referencias nulas me salen mucho

    1. Aris

      Saludos Luis.

      Cuando invocas al formulario Hijo debes tambien pasarle la referencia del padre,
      esto se hace cuando le asignas this a la propiedad del tipo de la interfaz en el formulario hijo

  7. arielqcero

    Funciona bien! tuve que prestar atencion en cada linea del codigo al principio porque no funcionaba.
    Probado en Visual Studio 2019 c#.

    Me habia olvidado colocar Icontract en esta parte:

    Padre : Form , IContract

    Gracias.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.