SilverLight 4 - Usando o controle DataGrid
Se você precisa criar aplicações que tratam com uma grande quantidade de dados, então um controle como o DataGrid do SIlverLight 4 é vital. Este controle exibe os dados em um formato tabular e permite a atualização, inclusão e exclusão de dados inline, bem como a ordenação dos dados em colunas através de um clique no cabeçalho e o agrupamento de forma que você pode criar níveis nos dados.
Desde a versão 2 o SilverLight possui um poderoso controle DataGrid que se apresenta como um boa solução para o tratamento de grande quantidade de informação em um navegador. Ele reside no namespace System.Windows.Controls mas não esta incluído por padrão nos assemblies que são instalados com o SilverLight. Ao utilizá-lo em sua aplicação o SilverLight irá embutir diversos assemblies em um arquivo XAP.
Com o objetivo de manter um bom desempenho o controle DataGrid do SilverLight possui uma recurso conhecido como UI virtualization que faz com que o SilverLight somente crie itens que estão atualmente visíveis. Dessa forma mesmo que você esteja tratando com milhões de linhas, o DataGrid irá ter um desempenho muito bom.
Neste artigo vamos criar uma aplicação SilverLight onde iremos ter o seguinte cenário:
Objetivo : Criar uma coleção de objetos Livros e exibir esta coleção e um controle DataGrid customizado;
premissas:
- Os usuários não poderão alterar
os dados nem mover as colunas do DataGrid;
- A apresentação visual do DataGrid deve ser customizada;
- Os separadores verticais das colunas deverão ser ocultos e os
horizontais deve ter uma cor diferente;
- Devemos tratar o evento LoadingRow que nos dá acesso aos
valores que estão vinculados e baseados neste valor vamos
realizar alterações a aparência visual das linhas;
Abra o Visual Web Developer 2010 Express Edition e crie um novo projeto com o nome SilverLight_DataGrid usando a linguagem Visual Basic;
No menu File-> New Project selecione Visual Basic -> SilverLight e a seguir o template SilverLight Application informando o nome SilverLight_DataGrid;
Clique em OK;
Na seguinte janela de diálogo apenas confirme as opções e clique em OK;
Será criado uma solução com dois projetos: O projeto SilverLight e o Projeto Web;
O controle DataGrid é definido no namespace System.Windows.Controls mas por padrão este namespace não esta relacionado quando criamos o aplicativo SilverLight.
Por isso no menu Project selecione Add Reference e na guia .NET selecione os componentes: System.Windows.Controls.Data e System.Windows.Controls.DataInput conforme a figura abaixo:
Agora devemos incluir as seguintes declarações no projeto:
System.ComponentModel.DataAnnotations
System.Windows.Controls.Data
System.Windows.Controls.Data.Input
System.Windows.Data
Vamos agora criar no projeto
SilverLight as classes Livro, Categoria e Idiomas
que irão servir como fonte de dados para a nossa aplicação e
serão o domínio de nossa aplicação;
Clique com o botão direito sobre o projeto SilverLight (SilverLight_DataGrid) e selecione Add Class informando a seguir o nome da classe;
1- Classe Livro.vb
Public Class Livro Public Property Titulo() As String Get Return m_Titulo End Get Set(ByVal value As String) m_Titulo = value End Set End Property Private m_Titulo As String Public Property Autor() As String Get Return m_Autor End Get Set(ByVal value As String) m_Autor = value End Set End Property Private m_Autor As String Public Property Paginas() As Integer Get Return m_Paginas End Get Set(ByVal value As Integer) m_Paginas = value End Set End Property Private m_Paginas As Integer Public Property Categoria() As Categoria Get Return m_Categoria End Get Set(ByVal value As Categoria) m_Categoria = value End Set End Property Private m_Categoria As Categoria Public Property Editor() As String Get Return m_Editor End Get Set(ByVal value As String) m_Editor = value End Set End Property Private m_Editor As String Public Property Idioma() As Idiomas Get Return m_Idioma End Get Set(ByVal value As Idiomas) m_Idioma = value End Set End Property Private m_Idioma As Idiomas End Class |
Repita o procedimento para classe Categoria.vb e inclua o seguinte código :
Public Enum Categoria Aventura Ficção Computação Biografia Poesias End Enum |
Faça o mesmo para a classe Idiomas.vb :
Public Enum Idiomas Inglês Italiano Espanhol Português End Enum |
Agora no arquivo code-behind de MainPage.xaml.vb vamos incluir o código no construtor conforme abaixo:
Private livroColecao As List(Of Livro) Public Sub New() InitializeComponent() carregaLivros() End Sub |
A rotina carregaLivros() é que irá preencher em memória a nossa coleção de objetos livros. Para isso vamos definir esta rotina com o seguinte código:
Private Sub carregaLivros() livroColecao = New List(Of Livro)() Dim livro1 As New Livro() livro1.Titulo = "ASP, ADO e banco de dados na web " livro1.Autor = "José Carlos Macoratti" livro1.Idioma = Idiomas.Português livro1.Paginas = 250 livro1.Editor = "Editora Visual Books" livro1.Categoria = Categoria.Computação livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "2001 Uma Odisséia no espaço" livro1.Autor = "Stanley Kubrick" livro1.Idioma = Idiomas.Português livro1.Paginas = 300 livro1.Editor = "Editora B" livro1.Categoria = Categoria.Ficção livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "A moreninha " livro1.Autor = "Jose de Alencar" livro1.Idioma = Idiomas.Português livro1.Paginas = 200 livro1.Editor = "Editora Cs" livro1.Categoria = Categoria.Aventura livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "Fernando Pessoa - O Cancioneiro " livro1.Autor = "Fernando Pessoa" livro1.Idioma = Idiomas.Português livro1.Paginas = 150 livro1.Editor = "Editora D" livro1.Categoria = Categoria.Poesias livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "ASP, ADO e banco de dados na web " livro1.Autor = "José Carlos Macoratti" livro1.Idioma = Idiomas.Português livro1.Paginas = 250 livro1.Editor = "Editora Visual Books" livro1.Categoria = Categoria.Computação livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "Poesias de Jorge Amado " livro1.Autor = "Jorge Amado" livro1.Idioma = Idiomas.Português livro1.Paginas = 250 livro1.Editor = "Editora E" livro1.Categoria = Categoria.Poesias livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "ASP, ADO e banco de dados na web " livro1.Autor = "José Carlos Macoratti" livro1.Idioma = Idiomas.Português livro1.Paginas = 250 livro1.Editor = "Editora Visual Books" livro1.Categoria = Categoria.Computação livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "Biografia de Roberto Carlos " livro1.Autor = "Jose Lima" livro1.Idioma = Idiomas.Português livro1.Paginas = 280 livro1.Editor = "Editora F" livro1.Categoria = Categoria.Biografia livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "Poeias de Carlos Drummond de Andrade " livro1.Autor = "Carlos Durmmond de Andrade" livro1.Idioma = Idiomas.Português livro1.Paginas = 250 livro1.Editor = "Editora VB" livro1.Categoria = Categoria.Poesias livroColecao.Add(livro1) livro1 = New Livro() livro1.Titulo = "ASP, ADO e banco de dados na web " livro1.Autor = "José Carlos Macoratti" livro1.Idioma = Idiomas.Português livro1.Paginas = 250 livro1.Editor = "Editora Visual Books" livro1.Categoria = Categoria.Computação livroColecao.Add(livro1) End Sub |
Dessa forma quando a aplicação for executada serão criados os objetos Livros , Categoria e Idiomas e a uma coleção de objetos Livros será populada com os dados para que possamos exibi-los no controle DataGrid.
A seguir, vamos adicionar
um controle DataGrid para o arquivo MainPage.xaml.
Por enquanto, não vamos adicionar as nenhuma propriedade no
DataGrid. É aconselhável adicioná-lo para a página
arrastando-o na caixa de ferramentas, para que o Visual Studio
adiciona as referências corretas para os assemblies necessários
no projeto, bem como acrescentar o mapeamento de espaço no
código XAML.
Remova a declaração AutoGenerateColumns =
"False" para que vamos ver todas as
propriedades da classe Livro aparecer no DataGrid. A seguinte
linha de código mostra um exemplo de DataGrid com o nome
definido para DataGrid1 que o valor padrão.
Neste momento o projeto deverá apresenta a seguinte estrutura:
Pois bem e como fazemos para exibir as informações no DataGrid ???
Ora, já temos as classes definidas , já temos a coleção de livros pronta para ser preenchida com os dados e já temos o DataGrid na página principal, o que falta ???
Faltam apenas um detalhe...
No arquivo MainPage.xaml.vb volte ao construtor e inclua a seguinte linha de código: DataGrid1.ItemsSource = livroColecao conforme abaixo
Private livroColecao As List(Of Livro) Public Sub New() InitializeComponent() carregaLivros() DataGrid1.ItemsSource = livroColecao End Sub |
Dessa forma , usando os recurso do DataBinding do SilverLight, a propriedade ItemsSource obtém uma coleção que é usada para gerar o conteúdo do controle DataGrid.
Se executarmos o projeto agora iremos obter:
Por padrão, o DataGrid é editável
pelo usuário, e para alterar este comportamento basta definir a
propriedade IsReadOnly como True para não
permitir que o usuário possa editar os dados no controle.
Podemos ainda bloquear a exibição definindo as propriedades CanUserResizeColumns
e CanUserReorderColumns para False, e assim não
permitimos aos usuários redimensionar nem reordenar as colunas
do DataGrid.
Então devemos incluir as seguintes linhas de código no arquivo MainPage.XAML:
<sdk:
DataGrid x: Name = "BookDataGrid"
AutoGenerateColumns
= "True "
CanUserReorderColumns
= "False"
CanUserResizeColumns
= "False"
IsReadOnly
= "True ">
</ SDK: DataGrid>
O DataGrid possui muitos mais recursos que podemos usar para
ajustar a sua aparência vamos então definir as seguinte
propriedades no controle:
RowBackground="#999999"
AlternatingRowBackground="#CCCCCC"
ColumnWidth="150"
RowHeight="30"
GridLinesVisibility="Horizontal"
HeadersVisibility="All"
HorizontalGridLinesBrush="Blue"
Vejamos o significado de cada uma delas:
- Nas propriedades RowBackground
e AlternatingRowBackground estamos alterando a
cor de fundo
- A propriedade ColumnWidth define a largura das
colunas;
- A propriedade RowHeight define a altura das
linhas;
- As propriedades GridLinesVisibility e HorizontalGridLinesBrush
definem se as linhas de grade serão exibidas;
- A propriedade HeadersVisibility especifica que
queremos um cabeçalho de linha no controle;
Executando o projeto depois destas alterações teremos:
Podemos incrementar ainda mais o nosso DataGrid e vamos fazer isso.
Vamos usar o evento LoadingRow que é acionado quando cada linha é carregada.
Vamos usar esse evento para ter acesso a cada linha e vamos alterar as suas propriedades com base em uma condição.
Vamos definir que se a categoria de um livro for Poesias a cor da linha deverá ficar com fundo amarelo.
Fazemos isso incluindo o código a seguir no evento LoadingRow:
Private Sub DataGrid1_LoadingRow(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEventArgs) Handles DataGrid1.LoadingRow Dim livroExibido As Livro = TryCast(e.Row.DataContext, Livro) 'verifica se a categoria do livro é Poesias e destaca a linha em amarelo If livroExibido.Categoria = Categoria.Poesias Then e.Row.Background = New SolidColorBrush(Colors.Yellow) e.Row.Height = 40 Else e.Row.Background = Nothing End If End Sub |
Agora é só alegria, vamos ver como ficou o nosso DataGrid ?
Do jeitinho que queríamos...
Para encerrar fica alguns lembretes:
- Ao compilar a
aplicação, os assemblies correspondentes são adicionados ao
arquivo XAP e isto ocorre pois ao instalar o plugin do
Silverlight, os arquivos não são instalados como parte do CLR.
O objetivo é manter o plugin com um tamanho o menor possível;
- No entanto quando usamos os arquivos em nossa aplicação eles
são embutidos na aplicação e isso resulta em um aumento no
tamanho do download do arquivo XAP;
- Na maioria das vezes, esse não é um problema. No entanto, se
o tamanho do arquivo é um item importante, então é essencial
ficar atento para este detalhe.
- Quando a propriedade AutoGenerateColumns é
definida como True (o padrão), o DataGrid usa reflection
sobre o tipo de objetos vinculados a ele. Para cada propriedade
pública que ele encontra, ele gera uma coluna correspondente.
Fora da caixa, o DataGrid inclui uma coluna de texto, uma coluna
checkbox, e uma coluna de modelo. Para todos os tipos que não
pode ser exibidos ,usa o método ToString e uma coluna de texto.
- Se quisermos que o DataGrid use o recurso de sincronização
automática, a coleção deve implementar a interface INotifyCollectionChanged.
Se as alterações para os objetos devem ser refletidas no
DataGrid, em seguida, os objetos da coleção deve-se implementar
a interface INotifyPropertyChanged
Simples , simples assim...
Pegue o projeto completo aqui: SilverLight_DataGrid.zip
Eu sei é apenas SilverLight 4 , mas eu gosto...
Referências: