André Alves de Lima

Talking about Software Development and more…

Enviando parâmetros de um formulário para o outro no Windows Forms e WPF

Trocar informações entre formulários é uma necessidade que, sem dúvida, todo programador precisará implementar nas suas aplicações uma hora ou outra. Esse é um aprendizado bem básico, mas que muita gente que está começando fica com dúvida e acaba implementando da pior maneira possível. Pensando nisso, eu resolvi gravar um vídeo bem curto e direto ao ponto, mostrando como enviar parâmetros de um formulário para o outro.

No vídeo eu utilizo um projeto Windows Forms, mas você pode utilizar o mesmo conceito no WPF, caso você não esteja trabalhando com a arquitetura MVVM. Confira o vídeo:

O projeto de exemplo

Nesse vídeo eu utilizei um projeto bem simples, uma vez que o único objetivo era mostrar como podemos fazer a troca de informações entre formulários. No formulário principal (Form1), temos dois TextBoxes e um botão:

A ideia é que, ao clicarmos no botão “Abrir Form2“, nós abriremos o segundo formulário da aplicação. Esse segundo formulário deverá receber o conteúdo que estiver digitado no TextBox “Parâmetro” do primeiro formulário.

No segundo formulário nós temos um TextBox e um botão:

Ao clicarmos no botão “Fechar” do segundo formulário, o conteúdo que estiver digitado no TextBox “Parâmetro” deve ser retornado para o primeiro formulário, mais especificamente no TextBox “Retorno“.

Parâmetros via construtor

A primeira possibilidade que podemos utilizar para enviarmos informações do primeiro formulário para o segundo formulário é através do construtor. Por padrão, os formulários só possuem um construtor padrão que não recebe nenhum parâmetro. Porém, nós podemos criar um segundo construtor no Form2. Esse construtor herdará do construtor principal, porém ele receberá uma string como parâmetro e utilizará o seu valor para preencher o TextBox:

        // C#
        public Form2(string parametro) : this()
        {
            textBoxParametro.Text = parametro;
        }
    ' VB.NET
    Public Sub New()
        InitializeComponent()
    End Sub

    Public Sub New(Parametro As String)
        Me.New()
        TextBoxParametro.Text = Parametro
    End Sub

Nota: no C#, não esqueça de herdar do construtor padrão, adicionando a chamada a “this()” na sua assinatura. Já no VB.NET, não esqueça de implementar manualmente o construtor padrão, que fará a chamada ao método “InitializeComponent”, que efetivamente adicionará os controles no formulário.

Com o construtor criado, nós podemos passar o valor do TextBox do primeiro formulário para o segundo formulário:

        // C#
        private void buttonAbrirForm2_Click(object sender, EventArgs e)
        {
            using (var form2 = new Form2(textBoxParametro.Text))
            {
                form2.ShowDialog();
            }
        }
    ' VB.NET
    Private Sub ButtonAbrirForm2_Click(sender As Object, e As EventArgs) Handles ButtonAbrirForm2.Click
        Using Form2 As New Form2(TextBoxParametro.Text)
            Form2.ShowDialog()
        End Using
    End Sub

Parâmetros via propriedade

Como pudemos ver acima, nós podemos passar informações do primeiro formulário para o segundo formulário através de parâmetros no construtor. Porém, para passarmos valores de volta do segundo formulário para o formulário principal, não dá para utilizarmos o construtor. Nesse caso, nós temos que criar uma propriedade no Form2 que dará acesso ao texto do TextBox:

        // C#
        public string Parametro
        {
            get { return textBoxParametro.Text; }
        }
    ' VB.NET
    Public ReadOnly Property Parametro As String
        Get
            Return TextBoxParametro.Text
        End Get
    End Property

Feito isso, nós conseguimos acessar o valor de retorno no primeiro formulário:

        // C#
        private void buttonAbrirForm2_Click(object sender, EventArgs e)
        {
            using (var form2 = new Form2(textBoxParametro.Text))
            {
                form2.ShowDialog();
                textBoxRetorno.Text = form2.Parametro;
            }
        }
    ' VB.NET
    Private Sub ButtonAbrirForm2_Click(sender As Object, e As EventArgs) Handles ButtonAbrirForm2.Click
        Using Form2 As New Form2(TextBoxParametro.Text)
            Form2.ShowDialog()
            TextBoxRetorno.Text = Form2.Parametro
        End Using
    End Sub

E com isso nós temos a troca completa de informações, tanto o envio de informações do Form1 para o Form2 quanto o retorno das informações do Form2 para o Form1.

Uma melhoria extra que podemos fazer nesse exemplo é adicionarmos um “setter” à nossa propriedade. Do jeito que o código está até agora, nós só conseguimos ler o valor da propriedade (ela é readonly). Se implementarmos um “setter” nessa propriedade, nós podemos trabalhar exclusivamente com ela na troca de informações, eliminando a necessidade de criarmos o construtor customizado:

        // C#
        public string Parametro
        {
            get { return textBoxParametro.Text; }
            set { textBoxParametro.Text = value; }
        }
    ' VB.NET
    Public Property Parametro As String
        Get
            Return TextBoxParametro.Text
        End Get
        Set(value As String)
            TextBoxParametro.Text = value
        End Set
    End Property

Em seguida, na criação do Form2, nós podemos utilizar a propriedade tanto para enviar o parâmetro como para receber o retorno:

        // C#
        private void buttonAbrirForm2_Click(object sender, EventArgs e)
        {
            using (var form2 = new Form2())
            {
                form2.Parametro = textBoxParametro.Text;
                form2.ShowDialog();
                textBoxRetorno.Text = form2.Parametro;
            }
        }
    ' VB.NET
    Private Sub ButtonAbrirForm2_Click(sender As Object, e As EventArgs) Handles ButtonAbrirForm2.Click
        Using Form2 As New Form2()
            Form2.Parametro = TextBoxParametro.Text
            Form2.ShowDialog()
            TextBoxRetorno.Text = Form2.Parametro
        End Using
    End Sub

Não faça isso!

Infelizmente, a pior implementação da trocar informações entre formulários ainda é muito utilizada por aí, que é a alteração do modificador de visibilidade dos controles para “público“. Essa modalidade é muito utilizada porque ela é extremamente fácil de ser implementada. Basta alterar uma propriedade do controle e pronto, teremos acesso irrestrito a todas as suas propriedades:

No vídeo eu mostro um exemplo concreto dos problemas que essa alternativa pode trazer para os nossos projetos. Ao alterarmos o modificador de visibilidade para “público“, nós teremos acesso irrestrito ao controle todo, e não somente à propriedade “Text“. Dessa maneira, nós podemos esconder ou remover o controle do segundo formulário, ou até mesmo alterar completamente o seu comportamento. Obviamente, essa não é uma boa prática, portanto, evite utilizá-la.

Concluindo

No vídeo de hoje você conferiu duas maneiras que podemos utilizar nos nossos projetos Windows Forms e WPF para trocarmos informações entre formulários. A primeira delas é através de parâmetros no construtor. Já a segunda alternativa é utilizarmos propriedades.

Através de parâmetros no construtor nós conseguimos enviar informações em um único sentido (do formulário chamador para o formulário receptor). Por outro lado, ao utilizarmos propriedades, nós conseguimos trocar informações nos dois sentidos.

E você, acredito que já precisou trocar informações entre formulários, não é mesmo? Qual dessas duas alternativas você utilizou? Ou você acabou implementando de alguma outra maneira? Conte-nos mais detalhes na caixa de comentários logo abaixo!

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.

Até a próxima!

André Lima

Photo by Peter Shanks used under Creative Commons
https://pixabay.com/en/startup-start-up-notebooks-creative-593327/

Song Rocket Power Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 3.0 License
http://creativecommons.org/licenses/by/3.0/

Newsletter do André Lima

* indicates required



Powered by MailChimp

20 thoughts on “Enviando parâmetros de um formulário para o outro no Windows Forms e WPF

  • deuzivaldo disse:

    Ótimo muito bom mesmo já estou criando um projeto para testar

    • andrealveslima disse:

      Muito obrigado, Deuzivaldo! Qualquer dúvida é só entrar em contato..

      Abraço!
      André Lima

      • Josiel Ferreira disse:

        Bom dia !
        Primeiro obrigado pela dica, resolveu uma parte do meu problema, eu estou coma seguinte situação, eu tenho um form 1 com um listview e chamo form2 porém eu precisava que ao digitar um valor no textbox do form2 fosse sendo inserido o no listview do form1, poderia me ajudar?
        Obrigado

        • andrealveslima disse:

          Olá Josiel.

          É só seguir a sistemática de envio de valores apresentada no artigo, provavelmente passando o valor desejado via propriedade.. Onde é que você está com dificuldade exatamente?

          Abraço.
          André Lima

  • Saulo J Freddi Jr disse:

    Realmente muito bom exemplos bem construidos

  • Ademi Vieira disse:

    Olá André! muito bom e útil, Parabéns mais uma vez!
    André, imagina o seguinte cenário: Um serviço WCF que será hospedado num servidor WEB (IIS), até este momento eu só consigo mudar a string de conexão do banco de dados através do arquivo Web.config.(muito chato), tem ferramentas capazes de ler o Web.config e fazer alterações? ou é melhor fazer tais coisas no código?

    Agradeço pela atenção.

    • andrealveslima disse:

      Olá Ademi!

      Normalmente as pessoas costumam trabalhar com strings de conexão no arquivo web.config (ou app.config) mesmo, ou em algum outro arquivo de configuração customizado da sua aplicação.. Strings de conexão direto no código é má prática e é algo que você deve evitar a todo custo..

      Eu não conheço ferramentas que façam a administração do web.config visualmente.. Eu sempre editei esses arquivos de configuração “na mão”.. Mas, se você pesquisar por “web.config tools”, você encontra algumas opções (eu não testei):

      Web Site Administration Tool Overview

      XDT (web.config) transform engine

      ASP.NET Web Site Administration Tool

      Se você encontrar alguma ferramenta interessante, volta aqui e conta pra gente..

      Abraço!
      André Lima

  • deuzivaldo disse:

    Ótimo professo. Muito bom mesmo. Obrigado

  • PAULO disse:

    André, bom dia!

    Novamente, excelentes exemplos e esclarecimentos a respeito de comunicação entre Forms.

    Se possível, gostaria de uma dica a respeito de como acessar um formulário de uma classe em outro projeto(camada) dentro da mesma solução.

    O cenário é o seguinte: Tenho um pequeno aplicativo que decidi construir no padrão MVVM (ou bem próximo disso).

    Na classe tenho um SUB “MostraCliente” que recebe como parâmetro o formulário específico. Na hora de manipular os controles dentro da SUB, não são disponibilizados os controles depois do ponto(.). Exemplo: frm. … nome_TextBox e assim por diante.

    Já fiz testes para isso de outra maneira, incluindo a classe no mesmo projeto(camada) do formulário e funcionou mas, do jeito que preciso não funcionou.

    E também já adicionei referências diversas aos projetos e também não deu certo.

    Exemplo da Sub.
    ————————————————————–
    Public Sub MostraCliente (Byval frm as Form_Cadastro_Cliente)


    frm.nome_TextBox.Text = …

    End Sub
    ————————————————————–

    Grato pela atenção.

    Paulo.

    • andrealveslima disse:

      Olá Paulo, muito obrigado pelo comentário!

      Imagino que você esteja trabalhando com Windows Forms, correto? Se esse for o caso, aparentemente uma solução seria alterar a visibilidade dos controles (propriedade “Modifiers” nos controles, a partir do designer do formulário).. Como você consegue acessar dentro do mesmo projeto, provavelmente o modificador de visibilidade está definido como “Internal”.. Para conseguir acessar os controles a partir de outro projeto, você precisa alterá-los para “public”..

      Caso você queira dispobilizar somente os valores dos controles (sem a possibilidade de alterá-los) seria criar propriedades que só permitem o acesso aos seus valores (propriedades read-only, que teriam somente a parte “Get”)..

      Abraço!
      André Lima

  • PAULO disse:

    André, boa tarde!

    Poderia me dar uma dica de como inserir um item numa ListView, com índice específico, sem perder o item anterior que estava no índice específico? Ou seja, inserir um item remontando a LIstView sem perda dos dados anteriores.

    Procurei por métodos no próprio controle e não consegui resolver. Já pensei em algumas rotinas para guardar os dados anteriores e depois atualizar a ListView.

    Grato pela atenção.

    Paulo.

    • andrealveslima disse:

      Olá Paulo!

      O ListView é bem flexível e pode ser exibido em diversos tipos de layout.. Às vezes a inserção de itens em uma posição específica acaba não funcionando corretamente.. Como está o layout do seu ListView? Quais propriedades você configurou nele?

      Eu começaria dando uma olhada nas sugestões desta thread do StackOverflow:

      Inserting an item into a C# Winforms listview

      Abraço!
      André Lima

  • PAULO disse:

    André, boa tarde!

    Novamente venho solicitar vossos sábios conselhos. Preciso mascarar uma coluna no DataGridView como data (__/__/____) e não consigo encontrar um evento KeyPress na célula específica para que quando o usuário for digitando os dados, eles sejam montados automaticamente naquele formato.

    Para os TextBoxs normais existe o evento KeyPress. Já no DGV não encontrei ainda.
    Obs: A maioria dos eventos sempre já aconteceu (Changed).

    Grato pela atenção!

    Paulo.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *