none
Acceder a objetos desde otro formulario en c# RRS feed

  • Pregunta

  • Buenas noches un cordial saludo colegas.

    Mi duda quizá es algo simple pero acabo de mudarme al lenguaje c# mi leguaje anterior era visual Basic y es la siguiente:

    anteriormente en VB si quería hacer referencia a un objeto de otro formulario simplemente ponía formulario.label.text="hola"

    pero ahora en c# parece que no tengo esa facilidad y no quiero crear una instancia nueva (Fom1 formulario = new Form1) por quien el formulario al que quiero acceder ya esta abierto no necesita hacer un show simplemente quiero tener acceso a un tabcontrol que esta en el formulario 1 desde mi formulario 2 eso es todo de antemano agradezco su ayuda y comprensión mil gracias

    domingo, 8 de noviembre de 2020 2:23

Respuestas

  • Cabe presumir que todos los demás formularios los has creado antes desde el formulario principal (que entiendo que es el que has llamado "contenedor"). Pues bien, desde dentro del propio formulario, su propia instancia se llama "this". Así que aunque no tengas acceso al sitio donde se crea, siempre puedes usar "this" para recuperar su instancia.

    Entonces, una vez que tienes esa instancia, como todos los demás los creas a partir del principal, cuando el principal crea los demás les puede pasar la instancia usando this. Se puede pasar a través de una propiedad, pero es más típico pasarla desde el constructor. Para ello, en cada uno de los formularios, modificas o añades un constructor así:

    private contenedor formularioPadre;
    
    public Form1(contenedor padre)
    {
        formularioPadre = padre;
    }
    
    // si más adelante quieres acceder al padre:
    ...
    formularioPadre.TabControl1.LoQueSea = ....

    Y a la hora de instanciar el formulario lo invocas así:

    Form1 formulario = new Form1(this);

    Observa el "this" que le pasamos al constructor. Esto es lo que luego le permite guardar en una variable interna la referencia al formulario llamante.


    domingo, 8 de noviembre de 2020 13:47
    Moderador

Todas las respuestas

  • anteriormente en VB si quería hacer referencia a un objeto de otro formulario simplemente ponía formulario.label.text="hola" pero ahora en c# parece que no tengo esa facilidad

    Sí, en C# la tienes, pero no funciona igual.

    Tu problema viene de que estás confundiendo la clase del formulario con la instancia del formulario. En el antiguo VB a veces no te das cuenta de esta diferencia porque VB automáticamente crea una instancia con el mismo nombre del formulario. Por ejemplo, si en VB tienes un formulario que se llama Form1, VB automáticamente hace lo siguiente internamente sin que tú lo escribas:

    Dim Form1 as New Form1

    El Form1 de la izquierda es la instancia, y el Form1 de la derecha es la clase. Por lo tanto, puedes acceder a la instancia con el nombre de la clase, porque las dos se llaman igual. Es lícito abrir en pantalla simultáneamente varias instancias de un mismo formulario, en cuyo caso sí que tendrías que escribir manualmente una línea como la anterior, poniendo un nombre diferente para cada instancia. Pero si solo abres una instancia, puedes usar ese nombre predeterminado, y por lo tanto acceder a ella con el mismo nombre de la clase.

    En C#, eso no es automático -- solo se crea la instancia si escribes tú el código para crearla. Y usualmente, para evitar confusiones, NO se suele usar el mismo nombre para las dos cosas. Por ejemplo, para abrir el Form1 harías esto:

    var frm = new Form1();

    Aquí la instancia es "frm" y la clase es "Form1".

    Para acceder a un objeto del formulario, tienes que usar la instancia y no la clase, es decir, en el ejemplo anterior sería frm y no Form1. Por ejemplo, para acceder al label:

    frm.label.Text="hola";

    Por supuesto, para que puedas hacer esto desde otro formulario, es necesario que la variable "frm" sea visible en dicho formulario. En VB, la variable esa que hemos dicho que se generaba internamente de forma automática era siempre una variable global. En C# no es automáticamente global, dependerá de cómo y donde la definas, así que depende de ti el declararla en algún sitio donde sea accesible al formulario desde donde la quieres usar. Podrías declararla como pública y estática si quisieras, pero normalmente se considera más elegante pasarla como argumento al formulario que la va a usar, para minimizar el uso de variables globales.

    domingo, 8 de noviembre de 2020 9:58
    Moderador
  • Primero que nada gracias por tu respuesta mira te explico mas a detalle el problema el form 1 se llama contenedor dentro de este form hay un tabcontrol donde en cada tabpage cargo un formulario diferente dentro de ella

    En cada formulario hay un botón que se llama inicio que te lleva al tabpage uno donde se encuentra el formulario inicio entonces desde cualquier formulario se tiene que poder acceder al control tabpage del formulario contenedor

    El detalle quiza es que no tengo idea de como crear una instancia del formulario principal ya que el se crea por defecto cuando carga el programa entonces no puedo o mas bien no entiendo en donde poner esa instancia de antemano gracias y buen dia

    domingo, 8 de noviembre de 2020 13:21
  • Cabe presumir que todos los demás formularios los has creado antes desde el formulario principal (que entiendo que es el que has llamado "contenedor"). Pues bien, desde dentro del propio formulario, su propia instancia se llama "this". Así que aunque no tengas acceso al sitio donde se crea, siempre puedes usar "this" para recuperar su instancia.

    Entonces, una vez que tienes esa instancia, como todos los demás los creas a partir del principal, cuando el principal crea los demás les puede pasar la instancia usando this. Se puede pasar a través de una propiedad, pero es más típico pasarla desde el constructor. Para ello, en cada uno de los formularios, modificas o añades un constructor así:

    private contenedor formularioPadre;
    
    public Form1(contenedor padre)
    {
        formularioPadre = padre;
    }
    
    // si más adelante quieres acceder al padre:
    ...
    formularioPadre.TabControl1.LoQueSea = ....

    Y a la hora de instanciar el formulario lo invocas así:

    Form1 formulario = new Form1(this);

    Observa el "this" que le pasamos al constructor. Esto es lo que luego le permite guardar en una variable interna la referencia al formulario llamante.


    domingo, 8 de noviembre de 2020 13:47
    Moderador
  • Hola mi estimado muchas gracias por tu tiempo y tu respuesta probare tu solución al igual que te comparto una manera mas de como hacerlo

    El Formulario contenedor creo:

     internal static TabControl dt;

    Cuando cargo el formulario principal le asigno a dt mi tabcontrol

    para despues porde acceder a el desde cualquier formulario 

    saludos¡¡¡

    domingo, 8 de noviembre de 2020 15:15
  • Hola juan manuel santiago

    Gracias por confirmar que se ha encontrado una solución a la consulta realizada. Debido a ello, este hilo será cerrado. 

    Si es necesario, por favor abra un nuevo hilo. 

    Gracias por usar los foros de MSDN. 

     

     Andres Aguilar

    ____________________________ 

      

    lunes, 9 de noviembre de 2020 17:28
    Moderador