sábado, 26 de setembro de 2009

Passagem de valores entre Forms em aplicações Windows em C#

Colocaram-me a questão de como passar valores entre janelas numa aplicação Windows em C#. Como trabalho substancialmente para a web não soube responder imediatamente, mas uma pesquisa no Google fez-me chegar rapidamente a uma solução. Este é um daquele tipo de coisas que pode ter muitas soluções, é caso para se aplicar o velho ditado "Cada cabeça, sua sentença"!

A solução que apresento é tão válida como outra qualquer, desde que responda à questão/problema inicial: "Como passar valores entre forms?".

Sendo que todos os forms são objectos e observando que o construtor é fundamental para o arranque do form (já que é ele quem invoca o método InitializeComponent() definido na parte Designer.cs dos forms, podemos usar precisamente o construtor para passar valores de um form para o outro.

Vamos "esmiuçar" (Gatos, gatos... o que vocês andam a fazer à sociedade portuguesa!) isto com mais cuidado. Vou criar uma Windows Application em C# com 2 forms com as designações por omissão dadas pelo Visual Studio (Form1 e Form2). Cada um destes Forms correspondem a uma classe que o VS subdivide em 2 partes, uma parte gerida pelo próprio ide (o ficheiro Form1.Designer.cs) e a outra parte que habitualmente usamos para tratar os eventos do form.


O Form1 vai conter uma caixa de texto e um botão que ao ser premido passará o valor escrito na caixa de texto para o Form2. Portanto o Form1 irá conter 2 controlos o textBox1 e o button1, o Form2 conterá apenas um label, o label1.

No Form2 vamos fazer o overload do construtor (uma característica importante da POO, que pode ser traduzido pela propriedade de podermos ter numa mesma classe diversos métodos com o mesmo nome, mas desde que cada uma das versões tenha uma lista de parâmetros diferente), por forma a passar como parâmetro o form1.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}

public Form2(Form1 frm): this()
{
label1.Text = frm.txt1.Text;
}
}
}



Desta forma, ao instanciarmos um objecto de Form2 podemos opcionalmente indicar que queremos passar para esse objecto um objecto da class Form1.

Agora podemos através do objecto frm na classe Form2 percorrer os controlos de Form1 ou então podemos tornar o objecto textBox1 do form1 como público! Podemos fazer isso facilmente trocando o acesso no ficheiro Form1.Designer.cs de privado para público Acrescentando uma propriedade pública ao Form1 correspondente ao controlo textBox1 (este método é mais seguro, já que não se alteram partes do código gerados pelo Visual Studio):


Agora no Form2 aceder à textBox1 do form1 é mais simples que descascar uma banana!




public Form2(Form1 frm): this()
{
label1.Text = frm.txt1.Text;
}



Agora já só falta associar ao evento click no form1 a abertura do form2:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this);
f2.Show();
}
}
}



O espectacular resultado final é este:


Um abraço e boas programações!

Sem comentários: