none
Como passar a classe de um objeto como parâmetro? RRS feed

  • Pergunta

  • Sou iniciante em C# e estou com uma dúvida.

    Fiz um método para criar alguns UserControls e colocá-los em TabControl, mas não consigo passar o classe do objeto como referência. O objetivo é ter um único método para as TabPages, mas não estou conseguindo informar o nome das classes que serão criadas.

    Estou fazendo assim:

     

    public void AddUserControl(UserControl ucNew, string

    titulo)

    {

     

    // cria a nova aba no PageControl

     

    TabPage

    novaPag = newPage(titulo);

    tbTelas.Controls.Add(novaPag);

     

    // cria o UserControl e o exibe na TabPage criada

    ucNew uc =

    new ucNew();

    // aqui que está o problema

    uc.Dock =

    DockStyle

    .Fill;

    uc.Parent = novaPag;

     

    this.tbTelas.SelectTab(this

    .tbTelas.TabCount - 1);

    }

     

    // pretendo criar os UserControls assim

     

    private void label1_Click(object sender, EventArgs

    e)

    {

    AddUserControl(ucCadCliente,

    "Cadastro de clientes"

    );

    }

    sexta-feira, 14 de outubro de 2011 01:50

Respostas

  • Olá Francisco,

    Acredito que do jeito que vc quer fazer não será possível, pois ao fazer desta forma vc não inicializa o seu UserControl, e assim, sem uma instância não é possível identificar o tipo de dados dentro do seu método, pois o mesmo está nulo.

    class ControlA : UserControl
    { }
    
    class ControlB : UserControl
    { }
    
    class Program
    {
        static void Main(string[] args)
        {
            ControlA a = null;
            ControlB b = null;
    
            CreateInstance(a);
        }
    
        static void CreateInstance(UserControl control)
        {   
            if (control is ControlA)
            {
                control = new ControlB();
            }
            else if (control is ControlB)
            {
                control = new ControlB();
            }
        }
    }
    


    Para fazer do modo que precisa é possível criar um método Factory e passar algum parâmetro que informe qual tipo de instância vc quer criar, como abaixo:

    class ControlA : UserControl
    { }
    
    class ControlB : UserControl
    { }
    
    enum UserControlEnum
    {
        ControlA,
        ControlB
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            ControlA a = null;
            ControlB b = null;
    
            CreateInstance(UserControlEnum.ControlA, a);
        }
    
        static void CreateInstance(UserControlEnum control, UserControl targetControl)
        {
            switch (control)
            {
                case UserControlEnum.ControlA:
                    targetControl = new ControlA();
                    break;
                case UserControlEnum.ControlB:
                    targetControl = new ControlB();
                    break;
            }
        }
    }
    

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    sexta-feira, 14 de outubro de 2011 15:13

Todas as Respostas

  • Olá Francisco,

    Pelo que entendi vc deseja passa o tipo de dados como parâmetro?

    Se é isso que vc precisa fazer então use o comando typeof.... desta forma:

    typeof(SeuTipoDeDados)


    Agora, se o seu problema são referências, onde o Visual Studio não consegue identificar o tipo das classes, e afirma que é um tipo desconhecido, procure digitar o nome da classe corretamente (Maiusculas e minusculas), depois clique com o botão direito do mouse sobre a classe, procure pela opção Resolve, e então o Visual Studio indicará um possível NameSpace para ser referênciado.

    Caso a opção Resolve não apareça, então seu projeto precisa fazer referência para outro possível Objeto.

     

    []S


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    sexta-feira, 14 de outubro de 2011 11:16
  • Olá Fernando,

    Eu quero sim passar o tipo de dados como parâmetro.

    Eu tenho vários userControls (ucClientes, ucMunicipios, ucProdutos ...) e quero criar uma instância de um determinado UserControl e adicioná-la na TabPage. A intenção é criar uma instância do UserControl do tipo que foi passado como parâmetro dentro da função AddUserControl.

    Exs.: AddUserControl(ucClientes, "Cadastro de clientes");  // aqui eu criaria uma instância do cadastro de clientes

    AddUserControl(ucMunicipios, "Cadastro de municípios");  // aqui eu criaria uma instância do cadastro de municípios

    AddUserControl(ucProdutos, "Cadastro de produtos");  // aqui eu criaria uma instância do cadastro de produtos

     

    Tentei usar o typeof mas não compilou.

     

    // versão simplificada da função

     public void AddUserControl(UserControl ucNew, string titulo)
            {
                typeof(ucNew) uc = new typeof(ucNew)();
                uc.Dock = DockStyle.Fill;
                uc.Parent = tabPage1;
            }

     

    Um abraço

    sexta-feira, 14 de outubro de 2011 12:30
  • Olá Francisco,

    O uso do typeof não é deste modo...

    Pelo oq vejo, vc recebe por parâmetro ucNew... Neste caso vc não precisa fazer nenhuma "reinicialização" dele dentro do código...

    No caso, vc não precisa da linha:

    ucNew uc = new ucNew(); 
    


    Fora que provavelmente o tipo de dados ucNew não existe... no caso vc está confundindo o nome da instância, com o nome do tipo de dados...

    Então, a resolução do seu problema é remover aquela linha, já que a instância do UserControl está sendo criada fora da chamada do seu método AddUserControl...

     

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    sexta-feira, 14 de outubro de 2011 12:39
  • Dá uma olhada em Generics onde consegue usar o  Tipo "T" sem saber quem é:

     

    static void Swap<T>(ref T lhs, ref T rhs)
    {
        T temp;
        temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
    

     


    Dá uma olhada nos links tb:

    http://stackoverflow.com/questions/1633690/generic-listt-as-parameter-on-method

    http://msdn.microsoft.com/en-us/library/twcad0zb%28VS.80%29.aspx

    http://www.dotnetperls.com/generic-method

    http://msdn.microsoft.com/pt-br/library/system.reflection.methodinfo.makegenericmethod.aspx


    Bruno Ferreira de Souza
    MSP - Microsoft Student Partner
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    MCC - Microsoft Community Contributor
    www.maestrodotnet.com.br
    @BrunoMaestro

    sexta-feira, 14 de outubro de 2011 14:16
  • Na verdade acho que não eu não soube explicar direito. A variável ucNew na verdade só será criada dentro do AddUserControl. Quando eu chamar a função AddUserControl eu não vou passar um usercontrol já inicializado. Eu pretendo criar uma variavel uc com o tipo que foi passado. Se eu passar ucCliente aí eu pretendo que a variável uc seja criada como ucCliente, se passar ucMunicipios uc seria criada como ucMunicipios.

    para eu não usar a linha "ucNew uc = new ucNew();" eu teria que chamar a função assim:

     private void button2_Click(object sender, EventArgs e)
    {

    ucClientes uc = new ucClientes();

    AddUserControl(uc, "Cadastro de clientes");

    }

     

    mas eu não queria ter que criar uma instância de uc para depois testar dentro da função AddUserControl se ela já existe nas TabPages

     

    obrigado pela atenção

    sexta-feira, 14 de outubro de 2011 14:44
  • O Generics serve para isso, dá uma olhada. Você passa o tipo e instancia ele dentro do método que quer sem saber o tipo dele.

    Bruno Ferreira de Souza
    MSP - Microsoft Student Partner
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    MCC - Microsoft Community Contributor
    www.maestrodotnet.com.br
    @BrunoMaestro

    sexta-feira, 14 de outubro de 2011 14:50
  • Olá Francisco,

    Acredito que do jeito que vc quer fazer não será possível, pois ao fazer desta forma vc não inicializa o seu UserControl, e assim, sem uma instância não é possível identificar o tipo de dados dentro do seu método, pois o mesmo está nulo.

    class ControlA : UserControl
    { }
    
    class ControlB : UserControl
    { }
    
    class Program
    {
        static void Main(string[] args)
        {
            ControlA a = null;
            ControlB b = null;
    
            CreateInstance(a);
        }
    
        static void CreateInstance(UserControl control)
        {   
            if (control is ControlA)
            {
                control = new ControlB();
            }
            else if (control is ControlB)
            {
                control = new ControlB();
            }
        }
    }
    


    Para fazer do modo que precisa é possível criar um método Factory e passar algum parâmetro que informe qual tipo de instância vc quer criar, como abaixo:

    class ControlA : UserControl
    { }
    
    class ControlB : UserControl
    { }
    
    enum UserControlEnum
    {
        ControlA,
        ControlB
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            ControlA a = null;
            ControlB b = null;
    
            CreateInstance(UserControlEnum.ControlA, a);
        }
    
        static void CreateInstance(UserControlEnum control, UserControl targetControl)
        {
            switch (control)
            {
                case UserControlEnum.ControlA:
                    targetControl = new ControlA();
                    break;
                case UserControlEnum.ControlB:
                    targetControl = new ControlB();
                    break;
            }
        }
    }
    

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    sexta-feira, 14 de outubro de 2011 15:13
  • Obrigado Fernando e Bruno pela ajuda.

    Assim funcionou

    sexta-feira, 14 de outubro de 2011 15:32
  • Usando Generics ficaria assim:

        private void button1_Click(object sender, EventArgs e)
        {
          Executa<UserControl1>();
          //Basta Passar o UserControl que quer
          //Executa<UserControl2>();
          //Executa<UserControl3>();
        }
        private void Executa<T>() where T : UserControl, new()
        {
          UserControl usr = new T();
          usr.Parent = this;
          usr.Show();
        }
    



    Bruno Ferreira de Souza
    MSP - Microsoft Student Partner
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    MCC - Microsoft Community Contributor
    www.maestrodotnet.com.br
    @BrunoMaestro

    sexta-feira, 14 de outubro de 2011 16:35