Introdução
Uma das críticas ao WPF era o fato de não ter disponível uma
DataGrid, para poder mostrar os dados em formato de tabela. Sem dúvida,
poderíamos usar a DataGrid WinForms usando os componentes de interoperabilidade
entre WPF e WinForms, mas esta seria uma solução muito aquém do esperado, pois
não poderíamos aplicar nosso estilo de apresentação, na DataGrid. Outra solução
seria usar a ListBox ou a ListView com um template de dados que permitisse a
edição, mas isto ainda não permitia a flexibilidade que uma DataGrid permite.
Finalmente, a Microsoft ouviu os pedidos e disponibilizou
uma DataGrid para WPF. Ela pode ser baixada (com o código fonte) junto com o
WPF toolkit em http://www.codeplex.com/wpf . O WPF Toolkit, além da DataGrid,
contém um DateTimePicker, um Calendário, temas para WPF e o VisualStateManager,
que permite criar estados para um componente e transições entre os estados: por
exemplo, o botão possui o estado MouseOver e o estado Pressed.
Podemos criar estilos para os botões nestes estados e definir animações para as
transições entre eles. Isto faz que o WPF fique semelhante ao Silverlight, que
usa o VisualStateManager para estilizar os componentes.
Uma vez baixado, o toolkit, você deve instalar o arquivo msi
que está incluído. Isto instala as referências para os novos assemblies.
Usando a DataGrid
Criaremos agora um projeto que lê dados de um banco de dados
usando LINQ to SQL e mostra os dados na DataGrid. Crie um novo projeto WPF. No
projeto adicione um novo LINQ to SQL classes e chame-o de NorthwindModel.dbml.
No Server Explorer, adicione uma nova conexão de dados, usando SqlServer File e
apontando para o lugar onde está o arquivo Northwind.mdf. Ao confirmar, a
conexão deve aparecer no Server Explorer. Abra o ramo tables da conexão e
arraste as tabelas Customers e Orders para o modelo. As tabelas e
sua relação são adicionadas ao modelo. Agora iremos criar a nossa interface de
usuário.
Para usar a DataGrid, devemos adicionar uma nova referêcia
ao projeto. Dê um clique com o botão direito do mouse no Project Explorer e
selecione a opção Add Reference e adicione o assembly WPFToolkit.
Uma vez adicionada a referência, precisamos adicionar o namespace no código
xaml. Isto é feito colocando a seguinte linha na declaração da janela, após os
demais namespaces:
xmlns:dg="clr-namespace:Microsoft.Windows.Controls;
assembly=WPFToolkit"
Em seguida, podemos colocar um componente DataGrid na
janela, dentro do component Grid de layout:
<dg:DataGrid x:Name="dataGrid"
AutoGenerateColumns="True" />
Estamos usando a propriedade AutoGenerateColumns,
configurando-a para True, de modo que a DataGrid crie colunas para os
nossos dados automaticamente. No construtor da janela, coloque o código que
carrega os dados para a DataGrid:
public Window1()
{
InitializeComponent();
var dc = new NorthwindModelDataContext();
dataGrid.ItemsSource = dc.Customers.ToList();
}
Aqui criamos o contexto de dados e atribuímos a coleção Customers
à lista de dados da DataGrid. Isto é o suficiente para alimentarmos os dados da
DataGrid, como mostra a Figura 1.

Figura 1 – DataGrid com dados da tabela de clientes
Esta DataGrid, apesar de simples, tem uma série de
características interessantes:
·
Classifica os dados clicando na coluna, ou mesmo classificar por
múltiplas colunas teclando Shift e clicando nas colunas desejadas
·
Redimensiona as colunas individualmente
·
Move as colunas de lugar
·
Permite inserir dados
·
Remove um dado quando teclamos Del
A inserção e deleção não são persistidas no banco de dados.
Como usamos o método ToList() para alimentar a DataGrid, temos apenas
uma coleção em memória, desligada do banco de dados. Para que os dados fossem
persistidos, precisaríamos fazer algo como:
dataGrid.ItemsSource = dc.Customers;
Mas neste caso, perdemos a capacidade de classificar os
dados, pois o LINQ to SQL traz os dados como Table<T> e isso faz que a
classificação não seja suportada nesta versão da DataGrid. Se você quiser usar
a classificação e persistir os dados, deve usar outro meio de acesso a dados,
como o Dataset, ou criar um mecanismo que capture as mudanças na coleção e
passe-as ao LINQ to SQL para que sejam persistidas, ou mesmo criar uma camada
de acesso a dados que faça toda a atualização das modificações, porém isto está
além do escopo deste artigo.
Mudando o estilo das linhas da DataGrid
A DataGrid, como todos os controles WPF, tem várias opções
de personalização. Podemos mudar as cores e fontes das linhas e cabeçalhos,
inclusive cores diferentes para linhas alternadas, criando uma tabela
“zebrada”. A maneira mais fácil de fazer isso é usar as propriedades AlternationCount,
que indica a quantas linhas a cor deve ser trocada, RowBackground e AlternatingRowBackground,
que indicam as cores das linhas. Por exemplo, o código abaixo permite gerar a
DataGrid conforme a Figura 2:
<dg:DataGrid x:Name="dataGrid"
AutoGenerateColumns="True"
AlternationCount="2" RowBackground="Beige"
AlternatingRowBackground="LightBlue">

Figura 2 – DataGrid “zebrada”
Podemos também mudar o estilo do cabeçalho, criando um novo
estilo. Inicialmente, criamos o novo estilo na seção Resources da
janela:
<Window.Resources>
<Style x:Key="columnHeaderStyle"
TargetType="Primitives:DataGridColumnHeader">
<Setter
Property="Background">
<Setter.Value>
<LinearGradientBrush
StartPoint="0.5,0"
EndPoint="0.5,1"
>
<LinearGradientBrush.GradientStops>
<GradientStop Color="Navy" Offset="0"
/>
<GradientStop Color="LightBlue" Offset="1"
/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter
Property="Foreground" Value="White"
/>
</Style>
</Window.Resources>
Em seguida, aplicamos este estilo à propriedade ColumnHeaderStyle:
<dg:DataGrid x:Name="dataGrid"
AutoGenerateColumns="True"
AlternationCount="2" RowBackground="Beige"
AlternatingRowBackground="LightBlue"
ColumnHeaderStyle="{StaticResource columnHeaderStyle}" />
Assim, obtemos uma DataGrid como a da Figura 3.

Figura 3 – DataGrid com o cabeçalho customizado
Podemos fazer mudanças mais radicais nas linhas, mudando o
seu estilo. Podemos criar um novo estilo para as linhas:
<Style x:Key="rowStyle" TargetType="dg:DataGridRow">
<Setter Property="FontFamily" Value="Verdana"
/>
<Setter
Property="FontSize" Value="10"
/>
<Style.Triggers>
<Trigger
Property="AlternationIndex" Value="0">
<Setter
Property="Background" Value="White"
/>
</Trigger>
<Trigger
Property="AlternationIndex" Value="1">
<Setter
Property="Background" Value="#DDDDDD"
/>
</Trigger>
<Trigger
Property="IsMouseOver" Value="True">
<Setter
Property="Background" Value="#BBBBBB"
/>
</Trigger>
</Style.Triggers>
</Style>