Abrindo Formulários Dinamicamente C# (Windows Forms)


Introdução


Uma tarefa comum no desenvolvimento de soluções Windows Forms é a necessidade de instanciar formulários com base no nome da classe, ou seja, como o desenvolvedor pode abrir um formulário dinamicamente (programaticamente) passando o nome deste formulário (classe) como string. Isto é muito comum quando há necessidade de criarmos menus populados dinamicamente a partir de uma base de dados.  


Problema


Apesar de representar uma necessidade comum em aplicações Windows Forms, ainda há muitas dúvidas entre os desenvolvedores de como implementar corretamente um procedimento para instanciar um formulário dinamicamente. Faltam exemplos sobre esse tipo prática e os que estão disponíveis na Web não são facilmente encontrados e na maioria das vezes são apresentados em outro idioma.


 Solução


Uma construção simples com o método CreateInstance do objeto Activator permite implementar esta funcionalidade. Veja o código abaixo:


 public static void OpenForm(string Namespace_FormName, bool System_Modal)


{


Type t = Type.GetType(Namespace_FormName);


if (t != null)


{


   System.Windows.Forms.Form f =


   (System.Windows.Forms.Form)Activator.CreateInstance(t);


   if (System_Modal)


      f.ShowDialog();


   else


   f.Show();


}


}


Instanciando um formulário implementado em outro assembly


Com uma construção semelhante, é possível iniciar um formulário implementado eu outro assembly. Basta modificar o código acima para incluir informações sobre o assembly externo. O exemplo abaixo mostra como iniciar um formulário (MDIChild) contido em outro assembly e centralizá-lo no MDI:


 privatevoid OpenChildFormFromExternalAssembly(


string Full_Namespace_Class,


string Root_Namespace,


string Assembly_Version,


string Assembly_Culture,


string Assembly_PublicKeyToken,


bool System_Modal)


{


Type t = Type.GetType(Full_Namespace_Class + “,” + Root_Namespace


+ “, Version=” + Assembly_Version


+ “, Culture=” + Assembly_Culture


+ “, PublicKeyToken=” + Assembly_PublicKeyToken);


if (t != null)


{


   System.Windows.Forms.Form f =


   (System.Windows.Forms.Form)Activator.CreateInstance(t);


   f.MdiParent = this;


   int TopMargin = 0;


         int LeftMargin = 0;


   LeftMargin = ((this.Width – f.Width) / 2) + this.Left;


         TopMargin = ((this.Height – f.Height) / 2) + this.Top – 50;


   f.StartPosition = FormStartPosition.Manual;


         f.Top = TopMargin;


   f.Left = LeftMargin;


   if (System_Modal)


      f.ShowDialog();


   else


      f.Show();


}


}


 As linhas abaixo demonstram como invocar o procedimento acima passando os parâmetros necessários:


 OpenChildFormFromExternalAssembly(


“EIS.Presentation.frmTipoEis”, // Namespace completo


“EIS”, // Root Namespace


“1.0.0.0″, // Assembly Version (AssemblyInfo.cs)


“neutral”, // Cultura (Default=neutral)


“null”, // PublicKeyToken (Default=null)


false


);


 

2 thoughts on “Abrindo Formulários Dinamicamente C# (Windows Forms)”

  1. Essa classe é de autoria minha, ajuda bastante tbm:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;

    namespace OTICA.Sistema
    {
    public static class Formularios
    {

    public static System.Collections.Generic.List forms = new List();

    ///

    /// Abre um formulário.
    ///

    /// Nova instancia do formulario que deseja abrir, caso ja exista uma ele desconsidera e elimina da memoria. ex: new Form1()
    /// Formulário MDI. Recipiente. Caso não haja nenhum insira null. ex: frmPrincipal ou null
    /// Se o formulário é Dialog ou não! Formulário que sobrepoem a aplicação.
    public static void abrir(Form frm, System.Windows.Forms.Form mdi_frm, bool dialog){
    bool aberto = false;
    for (int i = 0; i < forms.Count; i++) {
    if (frm.Name == forms[i].Name)
    {
    aberto = true;
    forms[i].Show();
    }
    }
    if (!aberto) {
    if (mdi_frm != null) {
    frm.MdiParent = mdi_frm;
    }
    forms.Add(frm);
    frm = forms[forms.Count - 1];
    if (dialog)
    {
    frm.ShowDialog();

    }
    else {
    frm.Show();
    }
    frm.Focus();
    }
    }

    ///

    /// Fecha um formulario. Elimina da memória.
    ///
    /// Adicionar o metodo Formularios.fechar(this); no evento FormClosed do formulario em questao.
    public static void fechar(System.Windows.Forms.Form frm) {
    for (int i = 0; i < forms.Count; i++) {
    if (frm.Name == forms[i].Name)
    {

    //frm.Close();
    forms[i].Dispose();
    forms.RemoveAt(i);
    frm = null;

    }
    }

    }

    }
    }

  2. Ótimo artigo.
    Gostei muito.
    Voce poderia me ajudar como fazer para capturar os nomes de todos os forms de um projeto ?
    Tentei usar Reflection, mas não retorna todos os formulários, somente alguns, e não sei o motivo.

    Agradeço antecipadamente.

    getulio.salasar@gmail.com

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>