2 10 2013
Criando um simples formulário de parâmetros em Windows Forms
Olá caro(a) leitor(a), seja bem vindo a mais um artigo!
No exemplo de hoje quero resgatar uma tecnologia um tanto quanto antiga, porém, ainda extremamente utilizada: Windows Forms. Introduzido em 2002 com o .NET Framework 1, o Windows Forms continua até hoje sendo muito utilizado, apesar de estar praticamente estagnado desde 2006 (quando a Microsoft introduziu o WPF). Desde então a Microsoft só tem corrigido bugs e feito pequenas melhorias no Windows Forms, optando por focar todas as suas forças no XAML, linguagem extensivamente utilizada para o desenvolvimento de aplicativos para as suas plataformas mais atuais: WPF, Silverlight, Windows Phone e aplicativos para a Windows Store (Metro Apps).
Enfim, eu estava hoje retornando aos fóruns da MSDN e me deparei com uma dúvida sobre como criar um formulário de parâmetros em Windows Forms. Lembro-me de ter visto questões sobre esse mesmo assunto no passado, quando eu participava mais ativamente dos fóruns. Portanto, resolvi escrever essa semana sobre esse tópico, que pode ser muito simples para muitos, mas bem complicado para outros. Se você reparar o andamento da thread, vai reparar que o autor inicialmente desenvolveu uma tela de parâmetros que recebia, no construtor, o Form que estava fazendo a chamada dessa tela de parâmetros. Claro que essa solução acarreta inúmeros problemas, principalmente dificultando a reusabilidade dessa tela, uma vez que para cada Form que quisesse acessar essa tela, o autor teria que criar um novo construtor na tela de parâmetros. Totalmente inviável.
Então, como é que eu resolveria essa questão? Eu criaria um Form de parâmetros que expõe uma propriedade com o item selecionado e, do Form que chamou essa tela de parâmetros eu acessaria essa propriedade. Pois bem, vamos então criar um exemplo prático passo-a-passo com essa ideia.
Primeiramente, crie um projeto Windows Forms e logo de cara renomeie o Form1 (que foi criado automaticamente no projeto) para FormPrincipal. Nesse Form, adicione um TextBox (chamado produtoTextBox) e um Button (chamado escolherProdutoButton), de forma que ele fique parecido com a imagem abaixo:
Veja abaixo uma tabela com as propriedades que eu alterei nesses controles:
Controle |
Propriedade |
Valor |
FormPrincipal |
ClientSize |
284, 76 |
FormPrincipal |
FormBorderStyle |
FixedSingle |
FormPrincipal |
MaximizeBox |
false |
FormPrincipal |
MinimizeBox |
false |
FormPrincipal |
Text |
Form Principal |
produtoTextBox |
Enabled |
false |
produtoTextBox |
Location |
13, 13 |
produtoTextBox |
Size |
259, 20 |
escolherProdutoButton |
Location |
13, 40 |
escolherProdutoButton |
Size |
259, 23 |
escolherProdutoButton |
Text |
Escolher Produto |
O próximo passo é criarmos o formulário que será utilizado para selecionar o Produto (a nossa tela de parâmetros). Para isso, adicione um novo Form ao projeto e dê o nome de FormParametro. Nesse novo Form, adicione um DataGridView (chamado produtosDataGridView) e dois Buttons (um chamado okButton e outro chamado cancelarButton). Ajuste o layout desse formulário de forma que ele se pareça com a imagem a seguir:
Mais uma vez, segue uma tabela com as propriedades que eu configurei neste formulário:
Controle |
Propriedade |
Valor |
FormParametro |
AcceptButton |
okButton |
FormParametro |
CancelButton |
cancelarButton |
FormParametro |
ClientSize |
425, 390 |
FormParametro |
FormBorderStyle |
FixedToolWindow |
FormParametro |
Text |
Escolha um Produto: |
produtosDataGridView |
AllowUserToAddRows |
false |
produtosDataGridView |
AllowUserToDeleteRows |
false |
produtosDataGridView |
Location |
13, 13 |
produtosDataGridView |
ReadOnly |
true |
produtosDataGridView |
SelectionMode |
FullRowSelect |
produtosDataGridView |
Size |
400, 336 |
okButton |
Location |
257, 355 |
okButton |
Size |
75, 23 |
okButton |
Text |
OK |
cancelarButton |
Location |
338, 355 |
cancelarButton |
Size |
75, 23 |
cancelarButton |
Text |
Cancelar |
Além disso, como você pode reparar, adicionei duas colunas ao DataGridView (colCodigoProduto e colDescricao). Essas colunas foram configuradas da seguinte maneira:
Controle |
Propriedade |
Valor |
colCodigoProduto |
DataPropertyName |
Codigo |
colCodigoProduto |
HeaderText |
Cod. Produto |
colDescricao |
DataPropertyName |
Descricao |
colDescricao |
HeaderText |
Descrição |
Agora é hora de criarmos a classe que vai representar os nossos Produtos. Obviamente este não é o foco deste exemplo, portanto, criaremos essa classe da forma mais simples possível, somente com duas propriedades: Codigo e Descricao. Adicione uma nova classe ao projeto, dando o nome de “Produto” e adicione essas duas propriedades nessa classe. O resultado final deve ficar algo como:
/// <summary> /// Classe que representa um simples Produto neste exemplo. /// </summary> public class Produto { /// <summary> /// Código do Produto. /// </summary> public int Codigo { get; set; } /// <summary> /// Descrição do Produto. /// </summary> public string Descricao { get; set; } }
O próximo passo é adicionar o código para alimentarmos o grid da nossa janela de parâmetros (FormParametro). Vamos colocar esse código no evento Load do FormParametro. Obviamente, estamos fazendo isso desta forma para simplificarmos um pouco o exemplo. No mundo real, você provavelmente alimentaria esse grid com dados vindo de um banco de dados. De qualquer forma, adicione o trecho de código a seguir no code behind de FormParametro e faça o link com o evento Load do Form:
/// <summary> /// Handler utilizado para o evento "Load" do Form de parâmetro. /// </summary> /// <param name="sender">O Form que disparou este evento.</param> /// <param name="e">Informações sobre o evento Load.</param> private void FormParametro_Load(object sender, EventArgs e) { // Aqui nós criamos uma lista de Produtos fictícia. Em um cenário real você provavelmente carregaria a lista de Produtos de um banco de dados. List<Produto> listaProdutos = new List<Produto>(); listaProdutos.Add(new Produto { Codigo = 1, Descricao = "Produto 1" }); listaProdutos.Add(new Produto { Codigo = 2, Descricao = "Produto 2" }); listaProdutos.Add(new Produto { Codigo = 3, Descricao = "Produto 3" }); listaProdutos.Add(new Produto { Codigo = 4, Descricao = "Produto 4" }); listaProdutos.Add(new Produto { Codigo = 5, Descricao = "Produto 5" }); listaProdutos.Add(new Produto { Codigo = 6, Descricao = "Produto 6" }); listaProdutos.Add(new Produto { Codigo = 7, Descricao = "Produto 7" }); listaProdutos.Add(new Produto { Codigo = 8, Descricao = "Produto 8" }); listaProdutos.Add(new Produto { Codigo = 9, Descricao = "Produto 9" }); listaProdutos.Add(new Produto { Codigo = 10, Descricao = "Produto 10" }); // O DataSource do DataGridView será a nossa lista de Produtos fictícia. produtosDataGridView.DataSource = listaProdutos; }
E então chegamos à parte mais importante do exemplo. Vamos criar uma propriedade neste Form que vai indicar qual foi o Produto selecionado para quem estiver utilizando essa tela de parâmetro. Chamemos essa propriedade de ProdutoSelecionado:
/// <summary> /// Caso um Produto tenha sido selecionado, esta propriedade guardará o Produto que foi selecionado. /// </summary> public Produto ProdutoSelecionado { get; set; }
Com isso, fica faltando somente o código onde iremos preencher essa propriedade e, logo em seguida, fechar o Form. Vamos criar um método para executar essas ações e vamos chamá-lo de SelecionarProdutoEFecharForm. Além disso, vamos implementar também dois event handlers que farão a chamada desse método quando o botão “OK” for clicado e quando o usuário executar um duplo-clique no grid de Produtos:
/// <summary> /// Handler utilizado para o evento "Click" do botão "OK". /// </summary> /// <param name="sender">O botão que disparou este evento.</param> /// <param name="e">Informações sobre o evento Click.</param> private void okButton_Click(object sender, EventArgs e) { // Quando o usuário clica no botão "OK", precisamos selecionar o Produto e fechar o Form. SelecionarProdutoEFecharForm(); } /// <summary> /// Handler utilizado para o evento "DoubleClick" do DataGridView de Produtos. /// </summary> /// <param name="sender">O DataGridView que disparou este evento.</param> /// <param name="e">Informações sobre o evento DoubleClick.</param> private void produtosDataGridView_DoubleClick(object sender, EventArgs e) { // Quando o usuário efetua um duplo clique no DataGridView, precisamos selecionar o Produto e fechar o Form. SelecionarProdutoEFecharForm(); } /// <summary> /// Preenche a propriedade "ProdutoSelecionado" com o Produto que está selecionado no DataGridView de Produtos e fecha o Form. /// </summary> private void SelecionarProdutoEFecharForm() { DialogResult = System.Windows.Forms.DialogResult.OK; if (produtosDataGridView.SelectedRows.Count > 0) ProdutoSelecionado = produtosDataGridView.SelectedRows[0].DataBoundItem as Produto; this.Close(); }
Finalmente, basta voltarmos ao FormPrincipal para criarmos a o event handler para o evento Click do botão “escolherProdutoButton“, que fará a chamada do FormParametro e definirá o texto do TextBox “produtoTextBox” com a descrição do Produto que foi selecionado na tela de parâmetros. Veja como fica esta parte final do nosso exemplo:
/// <summary> /// Handler utilizado para o evento "Click" do botäao "Escolher Produto". /// </summary> /// <param name="sender">O botão que disparou este evento.</param> /// <param name="e">Informações sobre o evento Click.</param> private void escolherProdutoButton_Click(object sender, EventArgs e) { // Construindo uma instância do FormParametro, exibindo-o e resgatando o Produto selecionado. using (FormParametro formParametro = new FormParametro()) { // Só continuamos caso o usuário confirme o diálogo e um caso um Produto tenha realmente sido selecionado. if ((formParametro.ShowDialog().Equals(System.Windows.Forms.DialogResult.OK)) && (formParametro.ProdutoSelecionado != null)) { produtoTextBox.Text = formParametro.ProdutoSelecionado.Descricao; } } }
Pronto! Execute o exemplo e veja que a tela de parâmetros é exibida com sucesso e, ao clicar no botão “OK” ou ao dar um duplo clique em um Produto, o TextBox “produtoTextBox” é preenchido com a descrição do Produto selecionado.
Caso você queira fazer o download do exemplo pronto, basta acessar o código no meu GitHub. Se você preferir, você pode também fazer o download deste exemplo na MSDN Code Gallery.
É isso aí pessoal, espero que este artigo ajude algum de vocês no futuro! Até a semana que vem!
André Lima
Detectando conexão à Internet em aplicativos para a Windows Store Microsoft MVP renovado pelo 4° ano!
Boa noite professor. Adorei, muito bom mesmo.
Serviu até para outro projeto. Agradeço
Obrigado
Olá Deuzivaldo! Obrigado pelo comentário! Fico feliz que o artigo tenha te ajudado no seu projeto..
Abraço!
André Lima
fiz tudo conforme descrito, mas quando clico duas vezes no grid, ele fecha e retorna para o outro form porem não preenche o txt box com nome
Olá Julio!
Como é que ficou o seu código dos formulários? Você poderia postar aqui para podermos dar uma olhada?
Abraço!
André Lima