Neste artigo, explicarei como trocar informações entre as janelas de uma aplicação Windows Forms. Os códigos de exemplo estão em C# mas no final do artigo também está disponível um sample em VB.NET.

Não existe apenas uma maneira para trocar dados entre Forms, mas no artigo serão abordadas três formas que considero úteis para a maioria dos casos: por construtor, pela referência de um Form aberto ou por EventHandler, mas primeiro vamos criar o visual da nossa aplicação.

Crie um novo projeto do tipo Windows Forms (C#) e adicione dois novos Forms, os nomes podem ficar como Form1 e Form2.

No Form1 adicione os seguintes controles:

  • label1: Label
  • textBox1: TextBox
  • btnAbrirForm2: Button
Form1
Form1

No Form2 adicione os seguintes controles:

  • textBox1: TextBox
  • textBox2: TextBox
  • textBox3: TextBox (Deixe o BackGround de outra cor, aqui coloquei verde)
  • lstProdutos: ListBox
  • btnEventHandler: Button
  • btnOpenForms: Button
Form2
Form2

Pronto! O visual da aplicação já está criado, agora vamos ao que interessa, a comunicação entre as duas janelas.

1. Por construtor:

A comunicação via construtor é a que eu julgo mais fácil, mas vai ser útil apenas quando a janela que você deseja passar os dados ainda não estiver aberta ou instanciada.

Adicione o seguinte código no Form2:

public Form2(List lista)
{
InitializeComponent();
foreach (string produto in lista)
{
lstProdutos.Items.Add(produto);
}
}

Neste código, estamos criando um novo construtor para o Form2, sendo obrigatória a passagem de uma lista de strings por parâmetro (que virá do Form1) e no nosso caso serão produtos, com essa lista vamos atualizar o lstProduto adicionando cada string contida na lista.

No Form1, adicione o seguinte código para o evento click do botão "Abrir Form2":

private void btnAbrirForm2_Click(object sender, EventArgs e)
{
List listaProdutos = new List();
listaProdutos.Add("Mouse");
listaProdutos.Add("Notebook");
listaProdutos.Add("Teclado");
Form2 form2 = new Form2(listaProdutos);
form2.Show();
}

Nesse código criamos uma lista de produtos de uma loja de informática e passamos por parâmetro para o Form2. Compile e execute a aplicação. Clique no botão "Abrir Form2".

Form2 aberto
Form2 aberto

Como você pode ver, o Form2 já veio com uma lista de produtos carregada, enviada pelo Form1, mas a comunicação ficará a seu critério, você pode passar quantos objetos você desejar e da maneira que precisar.

2. Pela referência de um Form aberto:

Esse tipo de comunicação é utilizada quando se deseja manipular um Form que já está aberto na aplicação, obtendo sua referência pela classe Application.

No Form2, adicione o seguinte código para o evento click do botão "OpenForms":

private void btnOpenForms_Click(object sender, EventArgs e)
{
//verifica se o Form1 está aberto
if (Application.OpenForms.OfType().Count() > 0)
{
Form form1 = Application.OpenForms["Form1"];
Label label1 = (Label)form1.Controls["label1"];
label1.Text = textBox1.Text;
form1.Text = textBox2.Text;
((TextBox)form1.Controls["textBox1"]).BackColor = textBox3.BackColor;
//aumenta o tamanho do form
form1.Size = new Size(400, 400);
}
else
{
MessageBox.Show("O Form1 não está aberto!");
}
}
[/sourcecode]

Através da propriedade Application.OpenForms, podemos encontrar uma coleção de Forms que estão abertos na aplicação, na primeira parte é verificado se o Form1 está aberto, caso ele esteja, pegamos sua referência e atribuímos à variável form1, atualizamos o Label, o TextBox e a propriedade Text do Form1 através de propriedades dos controles do Form2, veja também que não transferimos apenas dados entre os Forms, mas também atualizamos o tamanho de Form1.  Também é possível executar métodos e eventos do Form1, conforme sua necessidade.

Compile seu projeto e execute a aplicação, abra o Form2 através do botão criado no Form1, preencha os campos com os valores desejados e depois clique no botão "OpenForms" e veja o resultado obtido no Form1.

Resultado Form1
Resultado Form1

3. Por EventHandler:

A terceira e última forma mostrada no artigo é feita através de eventos e delegates, não vou entrar nesse assunto a fundo, mas caso você não conheça como funciona, segue as referências iniciais:

Delegates Tutorial (MSDN)

Events Tutorial (MSDN)

Adicione o seguinte código no Form2:

[sourcecode language="csharp"]
public delegate void OnDataChangeHandler(Hashtable info);
public event OnDataChangeHandler OnDataChange;
[/sourcecode]

Neste código, estamos criando o EventHandler e o delegate para o evento OnDataChange, que será o notificador de mudança do Form2, para que futuramente o Form1 possa ser atualizado.

Ainda no Form2, adicione o seguinte código para o evento click do botão "EventHandler":

[sourcecode language="csharp"]
private void btnEventHandler_Click(object sender, EventArgs e)
{
Hashtable info = new Hashtable();
info.Add("Valor1", textBox1.Text);
info.Add("Valor2", textBox2.Text);
info.Add("textBox3", textBox3);
OnDataChange(info);
}
[/sourcecode]

Note que estamos utilizado um Hashtable para guardar os objetos que queremos passar do  Form2 para o Form1, o Hashtable é passado por parâmetro no evento OnDataChange. Caso você não conheça um Hashtable, ele nada mais é do que uma tabela que server para guardar objetos vinculados à uma chave, veja a referência.

No Form1, adicione o seguinte linha para o evento click do botão "Abrir Form2", adicione também o método form2_OnDataChange:

[sourcecode language="csharp" highlight="8"]
private void btnAbrirForm2_Click(object sender, EventArgs e)
{
List listaProdutos = new List();
listaProdutos.Add("Mouse");
listaProdutos.Add("Notebook");
listaProdutos.Add("Teclado");
Form2 form2 = new Form2(listaProdutos);
form2.OnDataChange += new Form2.OnDataChangeHandler(form2_OnDataChange);
form2.Show();
}

private void form2_OnDataChange(Hashtable info)
{
label1.Text = info["Valor1"].ToString();
this.Text = info["Valor2"].ToString();
textBox1.BackColor = ((TextBox)info["textBox3"]).BackColor;
this.Size = new Size(300, 155);
}
[/sourcecode]

Para entender melhor o que se passa por aqui, pense como se fosse uma assinatura de uma revista, você deseja receber em sua casa todos os meses uma determinada revista, então você assina para que receba mensalmente a revista em sua casa, o Form1 faz exatamente isso, implementa o EventHandler OnDataChange de Form2 (assinar revista) criando o evento form2_OnDataChange (receber revista), toda a vez em que o botão "EventHandler" for clicado no Form2 (enviar revistas), esse evento será executado, note que você poderá fazer isso em quantos Forms você desejar e todos receberão a sua "revista".

No evento form2_OnDataChange, recebemos o Hashtable enviado por parâmetro pelo Form2, buscamos por cada chave de referência e atualizamos o Form1, note que alteramos novamente o tamanho do Form1.

Compile seu projeto e execute a aplicação, abra o Form2 através do botão criado no Form1, preencha os campos com os valores desejados e depois clique no botão "EventHandler" e veja o resultado obtido no Form1.

Por hoje vou ficando por aqui, espero que tenham aprendido, seguem os samples em C# e VB.NET, se divirta, comente, critique e não deixe de tirar as suas dúvidas.

Projeto C#
Projeto VB.NET

Abraços, Thiago Coelho!