none
Instancia de la clase RRS feed

  • Pregunta

  • Hola Buenos días, tengo una cuestión. Estoy trabajando con formularios y veníamos trabajando directamente con la instancia principal , ahora lo quiero hacer de manera dinámica a través de una cadena. Cómo genero la instancia principal de una clase (form) a través de una cadena y no una instancia nueva?

    EJ:

    Dim fm as new Formulario - Instancia nueva  
    fm.Show
    
    Formulario.Show() -Quiero lograr obtener la instancia principal
    Desde ya, gracias!



    lunes, 27 de noviembre de 2017 14:50

Respuestas

  • "Juanci González" escribió:

    > En el ejemplo veo que pasas la cadena, pero también el form que
    > corresponde y esa no sería una buena opción para mi
    >

    Me parece a mí que no has comprendido del todo el ejemplo. ;-)

    A la función GetForm solamente se le pasa el NOMBRE DEL FORMULARIO (una cadena alfanumérica), el cual devuelve un objeto de la clase System.Windows.Forms.Form, que es la clase base de la que heredan los restantes formularios que creamos en un proyecto de Windows Forms: Form1, Form2, Form138.

        Dim frm As Form = GetForm("Form1")
        frm.Show()

    Es decir, tenemos una variable objeto (frm) que referencia a la clase base de un formulario de nuestro proyecto llamado "Form1". Pero si en lugar de referenciar a la clase base, quieres referenciar exactamente el formulario Form1, Form2, Form138, no te va a quedar más remedio que convertir el objeto Form devuelto por la función GetForm en un objeto de la clase Form1:

       
    Dim frm As Form1 = DirectCast(GetForm("Form1"), Form1)

    También podrías hacer esto:

        ' Obtenemos el System.Type de la clase WindowsApplication.Form1.
        ' Necesitarás conocer el espacio de nombres completo del formulario.
        '
        Dim ty As Type = Type.GetType("WindowsApplication.Form1")
    
        ' Crear la instancia del formulario
        Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
        Dim frm As Form1 = DirectCast(asm.CreateInstance(ty.FullName), Form1)
        frm.Show()

    Pero necesitarás declarar explícitamente una variable del tipo Form1, Form2, Form138, si deseas trabajar con la instancia de un formulario concreto.

    En Visual Basic .NET se crean las instancias de los objetos, incluidos los formularios, de dos maneras: mediante el operador New (la más sencilla) o mediante reflexión si se conoce de antemano su System.Type. El inconveniente que tiene ésta última, y ya que estamos hablando de clases u objetos de formularios, es que no te va a quedar más remedio que trabajar con la clase base Form si desconoces el nombre del formulario cuya instancia deseas crear (Form1, Form2, Form138), por lo que NO PODRÁS ACCEDER a aquellas propiedades y métodos propios del formulario cuya instancia deseas crear. Para acceder a ellas tendrás que convertir explícitamente el objeto Form en Form1, Form2 o Form138.

    > Existe alguna forma de recorrer esos formularios en My?

    Pues lo mismo la habrá pero entiendo que estaremos en las mismas, porque para referenciarla necesitarás conocer el nombre del formulario concreto:

        Dim frm As Form = RecorrerFormulariosMy("Form1")

    Y si deseas trabajar con la instancia de un formulario concreto:

        Dim frm As Form138 = DirectCast(RecorrerFormulariosMy("Form138"), Form138)

    "RecorrerFormulariosMy" se comprende que es una función que supuestamente recorre los formularios del objeto My.Forms y que devuelve un objeto System.Windows.Forms.Form. Como entiendo que estaremos en las mismas, ¿para qué me voy a preocupar de averiguar si existe o no una manera de recorrer los formularios del objeto My? :-))

    Lo que tienes que ver es si puedes trabajar con una instancia de la clase Form o necesariamente tiene que ser con una instancia de un formulario concreto, porque para llamar a su método Show, entre otros muchos más, te basta con declarar una variable objeto del tipo System.Windows.Forms.Form.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.



    lunes, 27 de noviembre de 2017 18:39
    Moderador

Todas las respuestas

  • Buenas,

    Podrias hacerlo filtrando los formularios activos de la aplicacion:

    Dim m_form = Application.OpenForms.OfType(Of Formulario)().FirstOrDefault()
    If m_form IsNot Nothing Then
    	m_form.Show()
    Else
    	m_form = New Formulario()
    	m_form.Show()
    End If
    

    En el caso de que exista una instancia del formulario, la cargara, en caso contrario, creara una nueva (puedes borrar el else si no quieres una nueva en caso de que no haya ninguna previamente).

    Por otro lado, para usar esto, vas a necesitar añadir

    Imports System.LinQ

    Si tienes dudas nos comentas

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    lunes, 27 de noviembre de 2017 15:53
  • Hola Jorge, yo tengo almacenado el nombre de la clase del formulario en una tabla de SQL y por eso necesito hacerlo de forma dinámica, pasando como parámetro la cadena (pero abrir el default form y no una instancia)
    lunes, 27 de noviembre de 2017 16:40
  • "Juanci González" preguntó:

    > Formulario.Show() -Quiero lograr obtener la instancia principal

    Hola:

    Si por Formulario entendemos la INSTANCIA PREDETERMINADA que Visual Basic nos proporciona en TIEMPO DE EJECUCIÓN por cada uno de los formularios (objetos de la clase System.Windows.Forms.Form) existentes en nuestro proyecto, te diré que NO EXISTE una "instancia principal" como bien puede ser aquella que hayamos creado mediante el operador New:

        Dim fm As New Formulario()

    Instancias de objeto predeterminadas proporcionadas por My.Forms y My.WebServices

    Desarrollo con la función My

    Son instancias compartidas (Shared) que solamente el lenguaje Visual Basic .NET nos proporciona por compatibilidad con las versiones previas del mismo, para que nos sintamos como si estuviésemos trabajando todavía con Visual Basic 6.0. ;-)

    Ahora bien, si por casualidad te refieres a obtener la instancia compartida de un formulario concreto existente en el proyecto, entonces tan solo ejecutarías lo siguiente:

        ' Referenciamos la instancia compartida del formulario
        Dim frm As Formulario = My.Forms.Formulario
    
        frm.Show()

    > Cómo genero la instancia principal de una clase (form) a través de una cadena y no una instancia nueva?

    Si te refieres a crear una instancia nueva de un formulario cualquiera mediante su nombre (una cadena alfanumérica) en lugar de crearla mediante el operador New, en el siguiente enlace lo explico:

    Mostrar un formulario conocimiento su nombre

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.

    lunes, 27 de noviembre de 2017 16:47
    Moderador
  • Buenas,

    lo puedes hacer con reflexion:

    Dim formType As Type = Type.[GetType]("Nombre clase con namespace incluido")
    
    Dim m_form = Application.OpenForms.Cast(Of Form)().Where(Function(x) x.[GetType]() = formType).FirstOrDefault()
    If m_form IsNot Nothing Then
    	m_form.Close()
    End If

    te dejo documentación sobre como obtener el tipo desde nombre 

    Type.GetType

    Lo que se trata es de que cambies la inicializacion de la variable formType, para que en cuente el tipo de tu formulario, después lo busca mediante el where, y el resto es igual.

    Espero que no de errores de compilación, no soy programador VB y he traducido el código desde C#...

    Nos comentas el resultado

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:



    lunes, 27 de noviembre de 2017 16:48
  • Hola Enrique,

    Exacto la instancia predeterminada es la que quiero obtener, y que sea a través de una cadena. En el ejemplo veo que pasas la cadena, pero también el form que corresponde y esa no sería una buena opción para mi

    lunes, 27 de noviembre de 2017 17:23
  • Existe alguna forma de recorrer esos formularios en My? 
    lunes, 27 de noviembre de 2017 17:25
  • "Juanci González" escribió:

    > En el ejemplo veo que pasas la cadena, pero también el form que
    > corresponde y esa no sería una buena opción para mi
    >

    Me parece a mí que no has comprendido del todo el ejemplo. ;-)

    A la función GetForm solamente se le pasa el NOMBRE DEL FORMULARIO (una cadena alfanumérica), el cual devuelve un objeto de la clase System.Windows.Forms.Form, que es la clase base de la que heredan los restantes formularios que creamos en un proyecto de Windows Forms: Form1, Form2, Form138.

        Dim frm As Form = GetForm("Form1")
        frm.Show()

    Es decir, tenemos una variable objeto (frm) que referencia a la clase base de un formulario de nuestro proyecto llamado "Form1". Pero si en lugar de referenciar a la clase base, quieres referenciar exactamente el formulario Form1, Form2, Form138, no te va a quedar más remedio que convertir el objeto Form devuelto por la función GetForm en un objeto de la clase Form1:

       
    Dim frm As Form1 = DirectCast(GetForm("Form1"), Form1)

    También podrías hacer esto:

        ' Obtenemos el System.Type de la clase WindowsApplication.Form1.
        ' Necesitarás conocer el espacio de nombres completo del formulario.
        '
        Dim ty As Type = Type.GetType("WindowsApplication.Form1")
    
        ' Crear la instancia del formulario
        Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
        Dim frm As Form1 = DirectCast(asm.CreateInstance(ty.FullName), Form1)
        frm.Show()

    Pero necesitarás declarar explícitamente una variable del tipo Form1, Form2, Form138, si deseas trabajar con la instancia de un formulario concreto.

    En Visual Basic .NET se crean las instancias de los objetos, incluidos los formularios, de dos maneras: mediante el operador New (la más sencilla) o mediante reflexión si se conoce de antemano su System.Type. El inconveniente que tiene ésta última, y ya que estamos hablando de clases u objetos de formularios, es que no te va a quedar más remedio que trabajar con la clase base Form si desconoces el nombre del formulario cuya instancia deseas crear (Form1, Form2, Form138), por lo que NO PODRÁS ACCEDER a aquellas propiedades y métodos propios del formulario cuya instancia deseas crear. Para acceder a ellas tendrás que convertir explícitamente el objeto Form en Form1, Form2 o Form138.

    > Existe alguna forma de recorrer esos formularios en My?

    Pues lo mismo la habrá pero entiendo que estaremos en las mismas, porque para referenciarla necesitarás conocer el nombre del formulario concreto:

        Dim frm As Form = RecorrerFormulariosMy("Form1")

    Y si deseas trabajar con la instancia de un formulario concreto:

        Dim frm As Form138 = DirectCast(RecorrerFormulariosMy("Form138"), Form138)

    "RecorrerFormulariosMy" se comprende que es una función que supuestamente recorre los formularios del objeto My.Forms y que devuelve un objeto System.Windows.Forms.Form. Como entiendo que estaremos en las mismas, ¿para qué me voy a preocupar de averiguar si existe o no una manera de recorrer los formularios del objeto My? :-))

    Lo que tienes que ver es si puedes trabajar con una instancia de la clase Form o necesariamente tiene que ser con una instancia de un formulario concreto, porque para llamar a su método Show, entre otros muchos más, te basta con declarar una variable objeto del tipo System.Windows.Forms.Form.


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.



    lunes, 27 de noviembre de 2017 18:39
    Moderador