C#  - Apresentando a interface INotifyPropertyChanged


 Neste artigo vou rever os conceitos relacionados coma interface INotifyPropertyChanged usando a linguagem C#.
 
 A interface INotifyPropertyChanged

Você sabe o que faz a interface INotifyPropertyChanged ?

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

Acha pouco !!!!

Mas ela vai um pouco além...

A interface INotifyPropertyChanged proporciona um mecanismo unificado para definir em um único evento as propriedades Changed que queremos definir em nosso objetos.

Vamos pensar um pouco mais sobre isso...

Quando criamos um objeto, um controle ou um componente, geralmente implementamos um sistema para notificar o cliente (aquele que vai usar o controle/objeto) quando alguma de suas propriedades for alterada.

Isso é feito escrevendo eventos do tipo PropriedadeChanged para cada propriedade passível de alteração. Ora, isso poderia nos levar a ter que definir uma lista muito extensa de eventos, e, todos com a mesma finalidade :  notificar que o conteúdo de uma certa propriedade foi alterada.

Pensando nisso, foi introduzida na versão 2.0 da plataforma .NET, a interface System.ComponentModel.INotifyPropertyChanged que proporciona uma mecanismo para reunir em um único evento todos os eventos 'changed' de um objeto.

Vamos ver como isso funciona...

Implementando a interface INotifyPropertyChanged

Vamos criar uma aplicação Console Application usando o Visual Studio 2015 Community com o nome UsandoINotifyPropertyChanged.

A seguir vamos criar uma classe Aluno com duas propriedades :  Nome e Nota, um método AlterarNota(), e um construtor.

Abaixo temos o código da classe Aluno:

    public class Aluno
    {
        public string Nome { get; set; }
        public int Nota { get; set; }
        Aluno(string nome, int nota)
        {
            Nome = nome;
            Nota = nota;
        }
        public void AlterarNota()
        {
            Nota++;
        }
    }

Muito simples, não é mesmo !!!

Agora vamos implementar a interface INotifyPropertyChanged para esta classe.

(Obs: Existem outras maneiras de implementar a interface.)

using System.ComponentModel;
namespace UsandoINotifyPropertyChanged
{
    public class Aluno : INotifyPropertyChanged
    {
        private string nome;
        public string Nome
        {
            get { return nome; }
            set
            {
                if (nome != value)
                {
                    nome = value;
                    RaisePropertyChanged("Nome");
                }
            }
        }
        private int nota;
        public int Nota
        {
            get { return nota; }
            set
            {
                if (nota != value)
                {
                    nota = value;
                    RaisePropertyChanged("Nota");
                }
            }
        }
        public Aluno(string nome, int nota)
        {
            Nome = nome;
            Nota = nota;
        }
        public void AlterarNota()
        {
            Nota++;
        }
        //-- implementação da interface INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));        
        }
    }
}

Nessa classe implementamos a interface e definimos um evento (RaisePropertyChanged) que será disparado sempre que o valor de uma propriedade for alterada.

Recebendo notificações

Uma vez que implementamos a interface INotifyPropertyChanged em uma classe, podemos subescrever o evento PropertyChanged para uma instância da sua classe.

Se a implementação da interface foi feita corretamente o evento será disparado sempre que o valor da propriedade do objeto for alterada.

Para testar vamos incluir o código abaixo no arquivo Program.cs do projeto:

using System;
using System.ComponentModel;
namespace UsandoINotifyPropertyChanged
{
    class Program
    {
        static void Main(string[] args)
        {
            Aluno aluno = new Aluno("Macoratti", 7);
            aluno.PropertyChanged += aluno_PropertyChanged;
            aluno.Nome = "Jose Carlos Macoratti";
            aluno.AlterarNota();
            aluno.Nota = 6;
            Console.ReadLine();
        }
        private static void aluno_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Console.WriteLine(string.Format("Propriedade {0} acabou de ser alterada...", e.PropertyName));
        }
    }
}

O manipulador de eventos PropertyChanged recebe uma instância de um um objeto PropertyChangedEventArgs, que contém apenas uma propriedade PropertyName que lhe diz que a propriedade mudou.

Ele passa qualquer informação sobre o valor antigo ou sobre os novos valores da propriedade. A suposição é que o código do cliente pode ler o valor da propriedade atualizada por conta própria.

Para o exemplo estamos alterando o Nome e depois a propriedade Nota duas vezes.

Executando o projeto iremos obter o seguinte resultado:



Para que a notificação de alteração possa ocorrer em uma ligação entre um cliente e uma fonte de dados, o tipo vinculado deverá:

- Implementar a interface INotifyPropertyChanged (preferencial).       

  ou        

- Fornecer um evento de alteração para cada propriedade do tipo vinculado.

Nota : A partir da versão 5.0 da linguagem C# podemos usar o atributo CallerMemberName, do namespace System.Runtime.CompilerServices , para evitar ter que passar o nome da propriedade como  uma string.

Abaixo temos um exemplo de implementação da interface INotifyPropertyChanged em uma classe Pessoa que tem apenas a propriedade Idade usando o atributo CallerMemberName :

using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace UsandoINotifyPropertyChanged
{
    public class Pessoa : INotifyPropertyChanged
    {
        private int idade;
        public int Idade
        {
            get { return idade; }
            set
            {
                if (idade != value)
                {
                    idade = value;
                    RaisePropertyChanged();
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged([CallerMemberName]string prop = "")
        {
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
       }
    }
}

Usando este recurso o código fica mais simples.

Espero que você tenha entendido os fundamentos dessa importante interface.

Pegue o projeto aqui :  UsandoINotifyPropertyChanged.zip

Mas, ó homem, quem és tu, que a Deus replicas? Porventura a coisa formada dirá ao que a formou: Por que me fizeste assim?
Ou não tem o oleiro poder sobre o barro, para da mesma massa fazer um vaso para honra e outro para desonra?

Romanos 9:20,21

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