C# -  Implementando INotifyPropertyChanged com Windows Forms


 Neste artigo vou mostrar como implementar a interface INotifyPropertyChanged em uma aplicação Windows Forms usando controles vinculados para ter a exibição atualizada imediatamente nos controles.

Você sabe o que faz a interface INotifyPropertyChanged ?

Ela apenas notifica os clientes que um valor de uma propriedade foi alterado.

Pode parecer pouca coisa mas isso ajuda muito quando queremos atualizar automaticamente nossa interface do usuário quando ocorre alguma  mudança em nosso modelo de negócios e vice versa.

Este artigo usa uma aplicação Windows Forms bem simples onde um controle DataGridView exibe informações de uma classe Cliente, que aqui representa o nosso modelo de domínio.

O objetivo é mostrar que com a implementação de INotifyPropertyChanged pela classe Cliente qualquer mudança em suas propriedades serão notificadas e irão ser usadas para alterar o valor na interface com o usuário.

Acha pouco !!!!

Vamos ver como isso funciona...

Implementando INotifyPropertChanged com Windows Forms

Vamos criar uma aplicação Windows Forms Application usando o Visual Studio 2015 Community com o nome WF_INotifyPropertyChanged

No formulário form1.cs inclua um controle DataGridView - dgvClientes, um controle Button - btnAlterar e um BindingSource - bsCliente:

Disponha os controles conforme o leiaute da figura abaixo:

Vamos criar uma classe abstrata chamada NotifyBase onde iremos implementar a interface INotifyPropertyChanged:

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WF_InotifyPropertyChanged
{
    public abstract class NotifyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Essa classe abstrata apenas implementa a interface e usa o atributo CallerMemberName, do namespace System.Runtime.CompilerServices , para evitar ter que passar o nome da propriedade como uma string quando o método NotifyPropertyChanged() for chamado.

Vamos agora criar uma classe Cliente contendo as propriedades id,nome, email e idade  e que herda dessa classe abstrata:

using System;
namespace WF_InotifyPropertyChanged
{
    public class Cliente : NotifyBase
    {
        // campos que vão tratar valores para as propriedades publicas
        private Guid id = Guid.NewGuid();
        private string nome = String.Empty;
        private string email = String.Empty;
        private int idade = 0;
        // Método factory publico para criar cliente
        public static Cliente CriaNovoCliente()
        {
            return new Cliente();
        }
        public Cliente()
        {
            Nome = "Macoratti";
            Email = "macoratti@yahoo.com";
            Idade = 45;
        }
        public Guid Id { get { return id; } }
        public string Nome
        {
            get { return nome; }
            set
            {
                if (value != nome)
                {
                    this.nome = value;
                    //NotifyPropertyChanged();
                }
            }
        }
        public string Email
        {
            get { return email; }
            set
            {
                if (value != email)
                {
                    this.email = value;
                    //NotifyPropertyChanged();
                }
            }
        }
        public int Idade
        {
            get { return idade; }
            set
            {
                if (value != idade)
                {
                    this.idade = value;
                    //NotifyPropertyChanged();
                }
            }
        }
    }
}

Observe que a chamada do método NotifyPropertyChanged(), que notifica das alterações feitas nas propriedades, esta comentado para que possamos fazer a comparação antes e depois no teste.

Testando alterações na aplicação Windows Forms

Vamos incluir no evento Load do formulário o código abaixo que vai criar alguns dados, vincular o Binding Source com DataGridView e exibir os dados:

      private void Form1_Load(object sender, EventArgs e)
      {
            // Cria e preenche a lista de objetos Cliente
            // os quais irão fornecer os dados para exibir no DataGridView.
            BindingList<Cliente> listaClientes = new BindingList<Cliente>();
            listaClientes.Add(Cliente.CriaNovoCliente());
            listaClientes.Add(Cliente.CriaNovoCliente());
            listaClientes.Add(Cliente.CriaNovoCliente());
            // vincula a lista ao BindingSource.
            this.bsClientes.DataSource = listaClientes;
            // Anexa o BindingSource ao DataGridView.
            this.dgvClientes.DataSource = this.bsClientes;
     }

Para concluir, no evento Click do botão de comando inclua o código que vai alterar os dados selecionados no DataGridVIew:

        private void btnAlterar_Click(object sender, EventArgs e)
        {
            int linha = 0;
            //verifica se um existe um item selecionado
            if (dgvClientes.SelectedCells.Count > 0)
            {
                //obtem o indice da linha selecionada
                linha = dgvClientes.CurrentCell.RowIndex;
            }
            else
            {
                MessageBox.Show("Selecione uma linha para alterar");
                return;
            }
            // Pega a referencia da lista do BindingSource.
            BindingList<Cliente> listaCliente =
                   this.bsClientes.DataSource as BindingList<Cliente>;
            // altera o valor das propriedades para o item da lista
            listaCliente[linha].Nome = "José Carlos Macoratti";
            listaCliente[linha].Email = "(708)555-0150";
            listaCliente[linha].Idade = 55;
        }

Vamos agora testar:

1 - Com o código da chamada do método NotifyPropertyChanged na classe Cliente comentado:

Ao clicar no botão - Alterar Item - a interface não é atualizada e continua mostrando os dados antigos como se nada tivesse ocorrido.

2 - Com o código da chamada do método NotifyPropertyChanged na classe Cliente descomentado:

Agora com a implementa da interface INotifyPropertyChanged ativa ao clicar no botão - Alterar Item - a interface, representada pelo DataGridView é atualizada refetindo a alteração feita.

Quer mais ???

Pegue o projeto aqui :  WF_InotifyPropertyChanged.zip

E, como Moisés levantou a serpente no deserto, assim importa que o Filho do homem seja levantado;
Para que todo aquele que nele crê não pereça, mas tenha a vida eterna.

João 3:14,15

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?

 

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti