WPF - Apresentando o DataBinding


Os desenvolvedores para a plataforma Windows tem usado praticamente a mesma tecnologia de exibição por mais de 15 anos. Uma aplicação Windows básica se baseia em dois recursos muito usados do sistema operacional Windows para criar a interface com o usuário:

Ao longo dos anos essas duas tecnologias têm sido refinadas e as APIs que o desenvolvedores usam para interagir com elas tem mudado de forma dramática; mas se você esta criando uma aplicação com a plataforma .NET e WIndows Forms, ou ainda esta usando VB6, nos bastidores, os mesmos recursos do sistema operacional Windows estão sendo usados.

A tecnologia WPF veio para mudar este cenário ao trazer novos recursos e usar uma nova forma de trabalho que trabalha diretamente como a tecnologia DirectX.

O Microsoft Windows Presentation Foundation - WPF introduz uma nova maneira de criar interfaces com o usuário em clientes ricos oferecendo recursos gráficos e uma nova linguagem de marcação chamada XAML que é baseada em XML com um novo modelo de desenvolvimento que inclui um rico modelo para a ligação de dados.

O WPF efetua a separação do design da interface do usuário e do código de uma maneira parecida com ASP .NET onde temos em um arquivo a linguagem de marcação e em outro o código, o arquivo code-behind.

Um dos recursos mais poderosos apresentado pelo WPF é o databinding que permite efetuar a ligação com dados de diversas fontes de dados sem ter que utilizar código, permitindo gerenciar a execução e edição de dados complexos.

É isso mesmo, se você odeia codificar, vai amar o WPF, pois você pode através da linguagem declarativa de marcação (XAML) criar toda a interface com o usuário e efetuar a ligação de dados sem usar código.(Naturalmente tudo que você pode fazer no XAML você pode fazer via código).

Além disso o WPF apresenta as seguintes novas características na versão 3.5 (service pack1 do VS):

O que é o DataBinding

Para começar a usar o databinding com WPF você deve sempre definir um destino e uma origem.

O destino da ligação pode ser qualquer propriedade acessível ou elemento derivado da classe DependencyProperty. Um exemplo é a propriedade Text do controle TextBox.

A classe representa uma propriedade de dependência que é registrada com WPF. Propriedades de dependência fornecem suporte para expressões de valor, validação de propriedades e a coerção de valores dependentes, valores padrão, herança, a ligação de dados, animação, notificação e estilo.

A origem da ligação pode ser qualquer propriedade pública, incluindo propriedades de outros controles , objetos CLR, elementos XAML, datasets, arquivos XML, etc. A WPF oferece dois provedores especiais para ajudar na ligação de dados: XmlDataProvider e ObjectDataProvider.

O objeto XmlDataProvider permite Acessar aos dados XML declarativos para associação de dados.

XmlDataProvider expõe das seguintes maneiras para acessar dados XML:

  • Você pode incorporar dados usando a classe XmlDataProvider;
  • Você pode definir a propriedade Source para a URI uma arquivo de dados XML;
  • Você pode definir a propriedade Document para um XmlDocument;
A classe ObjectDataProvider envolve e cria um objeto que você pode usar como fonte de ligação de dados.

Há várias maneiras para criar um objeto para usar como uma fonte de ligação .Por exemplo, você pode criar o objeto na seção Recursos da página Linguagem de marcação de aplicativos extensível (XAML),ou você pode criar o objeto no código e defini-lo como DataContext.

O fluxo de dados na vinculação de dados ocorrer de duas formas básicas :

  1. Unidirecional (OneWay) - A alteração é feita somente na origem; Somente a propriedade do objeto é alterada; a fonte de dados não é alterada;
  2. Bidirecinal (TwoWay) - A alteração é feita na origem e no destino, ou seja, a alteração da propriedade altera a fonte de dados;
  3. OneWayToSource: É o inverso do OneWay. O que você alterar a propriedade destino a propriedade origem é alterada. Ou seja uma alteração na interface se reflete na origem de dados;

Para ficar mais claro vamos a um exemplo bem simples:

Você deseja exibir um valor de um campo de um banco de dados na propriedade Text de um controle TextBox.

No modo unidirecional o valor do campo é exibido na TextBox e não permite alteração (isso pode ser usado para campos do tipo somente-leitura)

No modo bidirecional o valor do campo é exibido e quando você altera o valor da TextBox a alteração é propagada para o banco de dados.

- DataBinding entre controles

Vejamos na prática como usar sintaxe da linguagem XAML para ligar a propriedade Text de um controle TextBox e a propriedade Value de um controle Slider:

<ProgressBar Text="{Binding ElementName=Slider, Path=Value}" Width="50" Height="20"/>

onde :

ElementName - indica o nome do controle que será a fonte de dados;
Path - indica a propriedade que será usada para preencher a propriedade Text da TextBox;

Em contrapartida o controle Slider precisaria ser definido assim:

<Slider Name="Slider" Width="150" Height="30" Maximum="100" />

- DataBinding entre um controle e uma fonte de dados

Agora vejamos como ficaria a declaração para a ligação entre a propriedade Text de um controle TextBox e o campo CategoryName da tabela Categories do banco de dados Northwind.mdb:

<TextBox Width="50" Height="20" Text="{Binding Path=CategoryName}" />

para definir se a ligação de dados é unidirecional ou bidirecional usamos a propriedade Mode:

<TextBox Width="50" Height="20" Text="{Binding Path=CategoryName, Mode=OneWay/TwoWay}" />

Além disso podemos usar o recurso de criar modelos e de usar a classe DataTemplate para a realizar a vinculação de dados.

No WPF os controles possuem um modelo padrão definido pelo sistema operacional. Você pode personalizar o visual de um controle através da criação de templates(modelos). Veja o exemplo abaixo:

			<Button x:Name="Botao1">
			    <Button.Template>
				<ControlTemplate>
				    <Ellipse Fill="Red"/>
				</ControlTemplate>
			    </Button.Template>
			</Button>			

Neste código estamos definindo que o botão fique com o formato de uma elipse através da criação de um template.

Usando a classe DataTemplate

O modelo data templating da WPF fornece a você uma grande flexibilidade para definir a apresentação de dados. Os controles WPF possui funcionalidades embutidas para suportar a personalização da apresentação dos dados.

Toda a funcionalidade de modelagem do WPF esta baseada na classe FrameworkTemplate.

A classe DataTemplate deriva de FrameworkTemplate como todas as outras classes usadas para o propósito da modelagem.

É muito mais fácil e rápido criar uma DataTemplate via declaração XAML do que usar código de programa. O código para criação de modelos atualmente é um tanto complexo e confuso, enquanto que a linguagem declarativa XAML é simples e limpa.

O DataTemplate pode gerar tantos elementos visuais quantos forem necessários para exibir o objeto de dados. Esses elementos usam ligações de dados para exibir os valores da propriedade do objeto de dados. Se um elemento não sabe como exibir o objeto que ele deve processar, ele simplesmente chama o método ToString nele e exibe o resultado em um TextBlock.

Uma outra característica da WPF que é usada em conjunto com os modelos é conhecido como 'triggers' (gatilhos). Um gatilho é algo como um bloco if usado no código procedural e somente executa o que o bloco contém quando uma condição avaliada for verdadeira.

Os triggers são disparados por condições como por exemplo os valores das propriedades, e permitem alterar os estilos dos objetos e efetuar diversas ações. Há diversos tipos de triggers mas os dois tipos básicos são :

Exemplo de ligação de dados

Vou encerrar este artigo com um exemplo prático de ligação de dados mais simples que existe : A ligação as propriedades de um elemento.

Neste exemplo temos um objeto origem que é um elemento WPF e sua propriedade Source que é uma propriedade de dependência.

Abra o Visual Studio 2008 e crie um novo projeto, menu File-> New Project, do tipo WPF Application com o nome wpf_DatBinding;

Na janela padrão Window1.xaml inclua a partir da ToolBox um controle Slider e um controle TextBlock no interior do leiaute Grid:

Define as propriedades dos controles conforme mostrado no arquivo XAML, segue abaixo o código usado:

Controle Slider:

 <Slider Height="22" Margin="30,22,24,0" Name="Slider1" 
                	   VerticalAlignment="Top"  Minimum="1"
	                Maximum="30" Value="10"
	                TickFrequency="1"
	                TickPlacement="TopLeft"
                />

Controle TextBlock:

      <TextBlock Margin="30,59,16,45" Name="TextBlock1" 
                   Text="Macoratti.net"
                   FontSize="{Binding ElementName=Slider1, Path=Value}"
                   />

Ao executar o projeto e mover o ponteiro do controle Slider o tamanho do texto irá ser alterado conforme você move para direita ou para esquerda, conforme a figura abaixo:

Veja que você não usou código apenas a poderosa linguagem declarativa de marcação  XAML. A declaração responsável pelo comportamento é :

  FontSize="{Binding ElementName=Slider1, Path=Value}"

Nesta declaração estamos vinculando a propriedade Value do Controle Slider1 a propriedade FontSize da propriedade Text do controle TextBlock.

No controle Slider configuramos apenas o valores máximo e mínimo.

Veja um exemplo de aplicação WPF com mais recursos em http://www.vertigo.com/familyshow.aspx (FamilyShow)

Faça o download dos fontes do FamlyShow em :  http://www.codeplex.com/familyshow/Release/ProjectReleases.aspx?ReleaseId=23637

O familyShow é uma aplicação WPF gratuíta disponibilizada sob a licença Ms-PL que permite baixar o código-fonte e abrí-lo. Então você pode baixar os fontes do FamilyShow e abrir no seu Visual Studio para estudar o código.

Você terá uma aplicação com uma excelente qualidade gráfica e com acesso a dados.

Com esta pequena introdução espero ter lançado alguma luz sobre o funcionamento do databinding do WPF. A seguir irei mostrar exemplos mais funcionais com vinculação a fonte de dados.

Eu sei é apenas WPF , mas eu gosto...


José Carlos Macoratti