.NET

8 abr, 2011

Arquitetura WPF – O DataBinding Final

Publicidade

Olá, pessoal!

Até aqui já vimos nos artigos anteriores (01 e 02) a criação do binding, fluxo de
dados, conversão de dados e os 4 elementos que compõem o mecanismo de binding. Já aprendemos bastante e ainda não acabou.

Nesta parte final, iremos
aprender sobre binding com coleções, validação e finalizar esta série de
artigos que teve por objetivo, passar o entendimento de como o mecanismo de
databinding dentro do WPF é diferenciado, como ele pode ser um aliado poderoso
na construção de aplicações corporativas.

Efetuando o Binding
com Coleções

Até aqui, abordamos cenários em que o binding é feito
utilizando como objeto fonte (source), um objeto único que contém várias
propriedades que podem ser utilizadas. Mais existem cenários, em que a
necessidade em questão, seja utilizar um conjunto de objetos e não somente um
único objeto como fonte de dados; a partir deste conjunto de objetos realizar
um filtro, pesquisa ou até mesmo um agrupamento de informações. É justamente em
cenários como este, que entra em ação o Binding com coleções.  Controles com a propriedade ItemsControl como
ListBox, TreeView ou ListView são comumente usados para visualizar estas
coleções. Atente para o diagrama abaixo:

Note que o diagrama utilizado é como os que foram utilizados
nos artigos anteriores. Ou seja, você liga a propriedade ItemsSource (propriedade de destino – target) a uma coleção de objetos como fonte de dados.
Note que a ligação é OneWay e a propriedade ItemsSource suporta binding por
omissão. Veja o exemplo:

A classe Tarefa utilizada no exemplo:

O
conde behind da janela do exemplo:

Na primeira figura, vemos destacado em vermelho a
declaração do objeto fonte de dados(source), através da declaração Source=Tarefas, que é uma propriedade
da janela que guarda uma Coleção de objetos do tipo Tarefa. E, destacado em azul, a declaração de qual propriedade terá
seu valor utilizado.

Veja que o binding com coleções é simples, semelhante ao
binding para um objeto único, exceto pelo fato de que o objeto fonte de dados
passa a ser um conjunto de objetos e não somente um objeto único.

É possível fazer
utilizar e iterar sobre qualquer coleção, que implemente a interface IEnumerable.
Uma funcionalidade interessante, é que
podemos ser notificados quando um item em uma determinada coleção é adicionado,
ou retirado. Para receber esta notificação, e a ela refletir na
tela para o usuário, temos que utilizar coleções que implemente a interface INotifyPropertyChanged.
O WPF fornece algumas destas coleções como ObservableCollection<T>,
BindingList<T>, Collection<T> ou até mesmo a
famosa List<T>.

CollectionViews

Como foi dito no
início, você pode querer filtrar, classificar agrupar…ou realizar
alguma ação relacionada ao conjunto de objetos que você possui como fonte de
dados. Para poder fazer isso você precisa utilizar coleções que implemente a
interface IcollectionView e ligá-la a seu ItemControl.

CollectionViews é uma camada sobre a
coleção de dados utilizada como fonte de dados, que permite realizar
operações nos objetos da coleção, sem ter que mudar a coleção de origem. Ou
seja, você pode navegar ou filtrar os objetos e a coleção de origem dos mesmo
não será alterada. A CollectionView também tem um ponteiro para o item atual
da coleção, como mostra a figura abaixo:

Um fato interessante é que por a CollectionView
não mudar a coleção de destino, você pode ter, na mesma tela, um controle que
exibe os dados de uma forma, e outro utilizando a mesma coleção exibindo os
mesmos dados de outra. Por exemplo, você pode ter um DataGrid com todos os
funcionários ordenado por nome e um outro DataGrid com os funcionários
ordenados por número de venda.

Uma maneira de utilizar CollectionViews é instanciar um
objeto do tipo CollectionViewSource
e utilizá-lo como Source. Observe o exemplo abaixo, o Binding é configurado
apontando para o objeto CollectionViewSource, ao invés de apontar para a
coleção diretamente.

  1. É instanciado
    declarativamente um objeto do tipo CollectionViewSource que será utilizado como
    source pela ListBox. O Binding é configurado por omissão {Binding}. Ou seja, os
    dados serão obtidos em tempo de execução. E vejam que tem um agrupamento
    configurado e apontando para a propriedade Nome da Turma.
  2. É declarado um
    DataTemplate (falaremos mais adiante), que será utilizado pelos itens da
    ListBox.
  3. O Binding não está
    apontando para a coleção diretamente, ao invés disso, ele aponta para o objeto
    CollectionViewSource de nole colecaoTurmas.
  4. Foi especificado
    na ListBox, qual template será utilizado para o agrupamento, no caso o template
    de nome TurmaTemplate.
  5. Está sendo
    declarado dentro da listbox, um DataTemplate, para cada item da listbox, no
    caso apontando para uma propriedade, dentro da classe Turma, que é uma coleção
    de alunos. Sendo configurado ainda que no Textblock a propriedade a ter seu
    valor utilizado, é a propriedade Nome, da classe aluno.

Se fosse necessário utilizar a mesma coleção, mas
com outra visão ou agrupamento, seria necessário apenas declarar outro objeto
CollectionViewSource com outro nome, e utilizar em um outro controle, mais
apontando para a mesma coleção.

Tipo de Coleção Source Tipo de Collectionview Notas
IEnumerable Um tipo interno baseado em CollectionView Não permite agrupar itens
IList ListCollectionView O mais rápido
IBindingList BindingListCollectionView Ação

Classificação de
Coleções

É possível aplicar uma
ordem aos itens da coleção. A CollectionViewSource, permite que seja alterada a
ordem em que estejam os itens da coleção, como também, estabelecer uma nova
ordem a partir de critérios. Veja o exemplo em que está sendo realizada uma
ordenação pela categoria e pela data inicial:

private void AddSorting(object sender, RoutedEventArgs args)
{

listingDataView.SortDescriptions.Add(
new SortDescription("Categoria", ListSortDirection.Ascending));
listingDataView.SortDescriptions.Add(
new SortDescription("DataInicial", ListSortDirection.Ascending));
}

Filtragem

Outro recurso muito útil
é a possibilidade de realizar filtros na coleção. E, com essas capacidades, você
pode ter controles distintos utilizando a mesma coleção, sendo que um controle
mostra os dados da coleção de uma forma, sendo que o outro pode mostrar as
informações a partir de um filtro feito sobre a mesma. Observe o exemplo
abaixo, em que é aplicado um filtro na coleção, em que só serão obtidos os
pedidos com valor acima de R$100,00:

listingDataView.Filter += new FilterEventHandler(MostraSomentePedidosValorAcimaCem);

Manipulador do evento

private void MostraSomentePedidosValorAcimaCem (object sender, FilterEventArgs e)
{
Pedido objPedido = e.Item as Pedido;

if (objPedido != null)
{
if (objPedido.Valor > 100)
{
e.Accepted = true;
}
else
{
e.Accepted = false;
}
}
}

Agrupamento

O Agrupamento permite
que a CollectionView particionar os itens da coleção em grupos lógicos. Os
grupos lógicos podem ser implícitos ou explícitos. Explícito quando o usuário
fornece uma lista de grupo e Implícitos quando os grupos são gerados
dinamicamente dependendo dos dados. O exemplo abaixo mostra o agrupamento por categoria:

PropertyGroupDescription objGroupDescription = new PropertyGroupDescription();
groupDescription.PropertyName = "Categoria";
listingDataView.GroupDescriptions.Add(groupDescription);

DataTemplates

DataTemplates são
templates que podem ser aplicados a itens dentro de um controle. Os
DataTemplates são muito úteis quando você deseja que os dados sejam exibidos
de alguma forma que não seja a habitual, podendo assim até alterar a aparência,
cor de fundo e outras características de um item de uma ListBox por exemplo.
Observe a figura abaixo:

Veja que o DataTemplate
está apontando para um tipo Aluno, e que o template contém um stackPanel de
orientação horizontal e um TextBlock que irá mostrar o nome do aluno. Esse
template mostrado acima será aplicado a cada item que for adicionado ao
ListBox, que será preenchido com uma coleção de objetos do tipo Aluno. Os
DataTemplates são muito poderosos e úteis, podendo ser configurados de acordo
com a necessidade da aplicação.

Chegamos
ao fim desta nossa série sobre o Mecanismo de Binding no WPF. Espero ter
ajudado e contribuído de alguma forma para o crescimento profissional de cada
leitor.

Um abraço e até a próxima.