VB .NET - Implementando o modo virtual do DataGridView |
Neste artigo vou mostrar como implementar o VirtualMode do controle DataGridView usando a linguagem VB .NET. |
Quando você deseja exibir grandes quantidades de dados em um controle DataGridView, você pode definir a propriedade VirtualMode como true e gerenciar explicitamente a interação do controle com seu armazenamento de dados. Isso permite que você ajuste o desempenho do controle nessa situação.
O modo
virtual é projetado para uso com repositórios muito grandes de dados. Quando a
propriedade VirtualMode for igual a true, você cria um DataGridView com
um número definido de linhas e colunas e, em seguida, invoca o evento
CellValueNeeded para preencher as células.
O modo virtual requer a implementação de um cache de dados subjacente para lidar
com o preenchimento, edição e exclusão das células do DataGridView com base em ações
do usuário..
O DataGridView fornece vários eventos que você pode manipular para interagir com
um armazenamento de dados personalizados. Neste artigo veremos o processo de
implementação desses manipuladores de eventos.
No exemplo vamos usar uma fonte de dados bem simples. Em um ambiente de produção, você normalmente carrega apenas as linhas que você precisa exibir em um cache e lida com eventos do DataGridView para interagir e atualizar o cache.
Recursos usados :
Criando o projeto no VS Community
Abra o VS Community 2015 e clique em New Project;
A seguir selecione Visual Basic -> Windows -> Windows Forms Application;
Informe o nome DataGridView_VirtualMode e clique no botão OK;
Vamos começar definindo a classe Cliente que será a nosso modelo de domínio e irá fornecer os dados para popular o DataGridView.
No menu Project clique em Add Class informe o nome Cliente e digite o código abaixo nesta classe:
Public Class Cliente
Public Sub New()
End Sub
Public Sub New(ByVal _nome As String, ByVal _email As String, _fone As String, _idade As Integer)
Nome = _nome
Email = _email
Telefone = _fone
Idade = _idade
End Sub
Public Property Nome() As String
Public Property Email() As String
Public Property Telefone() As String
Public Property Idade() As Integer
End Class
|
Agora vamos implementar o Datagridview usando o VirtualMode e os eventos necessários envolvidos neste processo.
1- Definindo o código inicial no formulário form1.vb
No formulário form1.vb vamos definir o código que contém uma inicialização básica, declarando algumas variáveis que serão usadas posteriormente no formulário.
Vamos definir também um método Main e definir um leiaute básico para o formulário no seu construtor.
Abaixo temos o código e resultado da execução do projeto neste estágio:
Public Class Form1
'define um objeto do tipo DataGridView
Private WithEvents dgvClientes As New DataGridView()
' Declara um ArrayList para servir como fonte de dados
Private clientes As New System.Collections.ArrayList()
' Declare um objeto Cliente para armazenar dadaos para uma linha sendo editada
Private clienteInEdit As Cliente
' Declare uma variável para armazenar o index da linha sendo editada
' O valor igual a -1 indica que não existe linha em edição
Private linhaInEdit As Integer = -1
' Declare uma variável para indicar o escopo do commit
' Defina o valor para False para usar o comite a nível de célula
Private linhaScopeCommit As Boolean = True
'define o método Main() que irá abrir o formulário
<STAThreadAttribute()>
Public Shared Sub Main()
Application.Run(New Form1())
End Sub
'no construtor do formulário vamos definir os valores de inicialização
'e incluir o datagridview nos controles de formulário
Public Sub New()
' Inicializa o formulário
'define as dimensões
Me.Width = 600
Me.Height = 400
'define o texto do formulário
Me.Text = "Usando o DataGridView no modo Virtual"
'preenche o form com o datagridview
Me.dgvClientes.Dock = DockStyle.Fill
'define a cor de fundo do datagridview
dgvClientes.BackgroundColor = Color.BlanchedAlmond
'incluir o datagridview nos controles do formulário
Me.Controls.Add(Me.dgvClientes)
End Sub
End Class
|
2- Definindo o código no evento Load para inicializar o datagridview e definir os dados
Agora no evento Load do formulário vamos digite o código abaixo:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' habilita o modo virtual
Me.dgvClientes.VirtualMode = True
' Adiciona colunas ao datagridview
Dim colunaNome As New DataGridViewTextBoxColumn()
With colunaNome
.HeaderText = "Nome"
.Name = "Nome"
End With
Dim colunaEmail As New DataGridViewTextBoxColumn()
With colunaEmail
.HeaderText = "Email"
.Name = "Email"
End With
Dim colunaTelefone As New DataGridViewTextBoxColumn()
With colunaTelefone
.HeaderText = "Telefone"
.Name = "Telefone"
End With
Dim colunaIdade As New DataGridViewTextBoxColumn()
With colunaIdade
.HeaderText = "Idade"
.Name = "Idade"
End With
Me.dgvClientes.Columns.Add(colunaNome)
Me.dgvClientes.Columns.Add(colunaEmail)
Me.dgvClientes.Columns.Add(colunaTelefone)
Me.dgvClientes.Columns.Add(colunaIdade)
'define o modo de exibição das colunas
Me.dgvClientes.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells
' Adiciona alguns dados a fonte de dados
Me.clientes.Add(New Cliente("Macoratti", "macoratti@yahoo.com", "11-99850-6666", 45))
Me.clientes.Add(New Cliente("Miriam", "mimi@hotmail.com.br", "11-8900-5200", 35))
Me.clientes.Add(New Cliente("Jefferson", "jeffi@bol.com.br", "21-87550-1002", 25))
Me.clientes.Add(New Cliente("Jessica", "jessicalang@hotmail.com", "61-9870-2580", 22))
Me.clientes.Add(New Cliente("Janice", "janjan@uol.com.br", "21-8870-4509", 20))
Me.clientes.Add(New Cliente("Larissa", "larissa@yahoo.com", "11-99850-6666", 15))
' Define a contagem da linha incluindo a linha para novos registros
Me.dgvClientes.RowCount = 6
End Sub
|
A figura ao lado mostra o resultado da execução do projeto neste estágio.
3- Implementar o tratamento do evento CellValueNeeded para exibir os dados no datagridview
O evento CellValueNeeded retorna o valor da células a partir da fonte de dados definida que é o objeto Cliente atualmente em edição.
Este evento ocorre sempre que o DataGridView desenha uma célula no grid.
Este evento é usado no modo virtual para popular as células com dados a partir da fonte de dados sem fazer com que as células se tornem não compartilhadas.
Private Sub dgvClientes_CellValueNeeded(ByVal sender As Object,
ByVal e As System.Windows.Forms.DataGridViewCellValueEventArgs) Handles dgvClientes.CellValueNeeded
' Se esta é a linha para novos registros nenhum valor é preciso
If e.RowIndex = Me.dgvClientes.RowCount - 1 Then
Return
End If
'define um objeto do tipo Cliente
Dim clienteTmp As Cliente = Nothing
' Armazena a referencia para o objeto Cliente para a linha sendo desenhada
If e.RowIndex = linhaInEdit Then
clienteTmp = Me.clienteInEdit
Else
clienteTmp = CType(Me.clientes(e.RowIndex), Cliente)
End If
' Defina o valor da célula a ser exibida usando o objeto Cliente retornado
Select Case Me.dgvClientes.Columns(e.ColumnIndex).Name
Case "Nome"
e.Value = clienteTmp.Nome
Case "Email"
e.Value = clienteTmp.Email
Case "Telefone"
e.Value = clienteTmp.Telefone
Case "Idade"
e.Value = clienteTmp.Idade
End Select
End Sub |
A figura ao lado mostra o resultado da execução do formulário neste estágio.
4- Implementar o tratamento do evento CellValuePushed para armazenar o valor de uma célula editada
O evento CellValuePushed ocorre no modo virtual sempre que o usuário confirma a alteração do valor de uma célula armazenando o valor na fonte de dados.
Este evento é usado para atualizar a fonte de dados. (Para retornar o valor da fonte de dados usamos o evento CellValueNeeded)
Private Sub dgvClientes_CellValuePushed(ByVal sender As Object,
ByVal e As System.Windows.Forms.DataGridViewCellValueEventArgs) Handles dgvClientes.CellValuePushed
'cria um objeto do tipo Cliente
Dim clienteTmp As Cliente = Nothing
' Armazena a referência para o objeto CLiente para a nova linha sendo editada
If e.RowIndex < Me.clientes.Count Then
' Se o usuário esta editando uma nova linha cria um novo objeto Cliente
If Me.clienteInEdit Is Nothing Then
Me.clienteInEdit = New Cliente(
CType(Me.clientes(e.RowIndex), Cliente).Nome,
CType(Me.clientes(e.RowIndex), Cliente).Email,
CType(Me.clientes(e.RowIndex), Cliente).Telefone,
CType(Me.clientes(e.RowIndex), Cliente).Idade)
End If
clienteTmp = Me.clienteInEdit
Me.linhaInEdit = e.RowIndex
Else
clienteTmp = Me.clienteInEdit
End If
' Define a propriedade do objeto Cliente para a célula informada
Dim novoValor As String = TryCast(e.Value, String)
Select Case Me.dgvClientes.Columns(e.ColumnIndex).Name
Case "Nome"
clienteTmp.Nome = novoValor
Case "Email"
clienteTmp.Email = novoValor
Case "Telefone"
clienteTmp.Telefone = novoValor
Case "Idade"
clienteTmp.Idade = novoValor
End Select
End Sub
|
5- Implementar o tratamento do evento NewRowNeeded para criar novos dados
Este evento ocorre sempre que o usuário informa um linha para novos registros permitindo que uma nova entrada seja criada na fonte de dados para uma nova linha. Permite também popular a linha com valores padrão.
Private Sub dgvClientes_NewRowNeeded(ByVal sender As Object,
ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgvClientes.NewRowNeeded
' Cria uma novo objeto Cliente quando o usuário edita a linha para novos registros
Me.clienteInEdit = New Cliente()
Me.linhaInEdit = Me.dgvClientes.Rows.Count - 1
End Sub
|
6- Implementar o tratamento do evento RowValidated para salvar alterações
Este evento ocorre depois que uma linha teve a sua alteração finalizada ou seja quando o usuário altera a linha atual. Ele é similar ao evento Validate e é usado para realizar o processamento posterior em uma linha de valores.
Private Sub dgvClientes_RowValidated(ByVal sender As Object,
ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvClientes.RowValidated
' Salva as alterações feitas em uma linha
If e.RowIndex >= Me.clientes.Count AndAlso
e.RowIndex <> Me.dgvClientes.Rows.Count - 1 Then
' Adiciona um novo objeto Cliente à fonte de dados
Me.clientes.Add(Me.clienteInEdit)
Me.clienteInEdit = Nothing
Me.linhaInEdit = -1
ElseIf (Me.clienteInEdit IsNot Nothing) AndAlso
e.RowIndex < Me.clientes.Count Then
' Salva o objeto Cliente modificado na fonte de dados
Me.clientes(e.RowIndex) = Me.clienteInEdit
Me.clienteInEdit = Nothing
Me.linhaInEdit = -1
ElseIf Me.dgvClientes.ContainsFocus Then
Me.clienteInEdit = Nothing
Me.linhaInEdit = -1
End If
End Sub
|
7- Implementar o tratamento do evento RowDirtyStateNeeded
A implementação do evento RowDirtyStateNeeded indica se o evento CancelRowEdit irá ocorre quando o usuário pressiona a tecla ESC duas vezes no modo de edição ou uma vez fora do modo de edição.
Por padrão o evento CancelRowEdit ocorre sobre a reversão da operação em uma linha quando qualquer célula da linha atual foi modificada a menos que a propriedade QuestionEventArgs.Response seja definida como True no tratamento de evento RowDirtyStateNeeded.
Este evento é útil quando o escopo do commit dos dados for determinado em tempo de execução.
Private Sub dgvClientes_RowDirtyStateNeeded(ByVal sender As Object,
ByVal e As System.Windows.Forms.QuestionEventArgs) Handles dgvClientes.RowDirtyStateNeeded
If Not linhaScopeCommit Then
' No escopo de confirmação a nível de célula (cell-level)
' indica se o valor da célula atual foi modificado
e.Response = Me.dgvClientes.IsCurrentCellDirty
End If
End Sub
|
8- Implementar o tratamento do evento CancelRowEdit para descartar os valores da linha atual
Este evento ocorre quando o usuário cancela a operação pressionando a tecla ESC duas vezes ou uma vez fora da edição. O evento não ocorre se nenhuma célula na linha atual foi modificado ou se o valor da propriedade QuestionEventArgs.Response foi definida como true no evento RowDirtyStateNeeded.
Private Sub dgvClientes_CancelRowEdit(ByVal sender As Object,
ByVal e As System.Windows.Forms.QuestionEventArgs) Handles dgvClientes.CancelRowEdit
If Me.linhaInEdit = Me.dgvClientes.Rows.Count - 2 AndAlso
Me.linhaInEdit = Me.clientes.Count Then
' Se o usuário cancelou a edição de uma nova linha criada
' substitui o objeto Cliente com um novo objeto vazio
Me.clienteInEdit = New Cliente()
Else
' Se o usuário cancelou a edição de uma linha existente
' libera o objeto cliente correspondente
Me.clienteInEdit = Nothing
Me.linhaInEdit = -1
End If
End Sub
|
8- Implementar o tratamento do evento UserDeletingRow que deleta dados
O evento UserDeletingRow ocorre sempre que o usuário deleta uma linha selecionando-a e pressionando a tecla DELETE.
Este evento deleta um objeto Cliente da fonte de dados ou descarta um objeto cliente ainda não salvo.
Private Sub dgvClientes_UserDeletingRow(ByVal sender As Object,
ByVal e As System.Windows.Forms.DataGridViewRowCancelEventArgs) Handles dgvClientes.UserDeletingRow
If e.Row.Index < Me.clientes.Count Then
' Se o usuário deletou uma linha existente
' remove o objeto Cliente correspondente da fonte de dados
Me.clientes.RemoveAt(e.Row.Index)
End If
If e.Row.Index = Me.linhaInEdit Then
' Se o usuário deletou uma nova linha libera
' o objeto cliente correspondente
Me.linhaInEdit = -1
Me.clienteInEdit = Nothing
End If
End Sub
|
Dessa forma temos os eventos que ocorrem no modo virtual e que são necessários para realizar as operações de alteração, inclusão e exclusão de dados no DataGridView.
Assim, se você desejar usar o DataGridView no modo virtual você não deverá vincular dados ao controle usando a propriedade DataSource.
Ao invés disso você deverá trabalhar com a propriedade RowCount e fornecer o tratamento para os seguintes eventos que somente ocorrem no modo virtual:
Evento | Descrição |
---|---|
CellValueNeeded | Usado para retornar e exibir o valor da célula a partir da fonte de dados em cache. Esse evento ocorre somente para células com colunas não vinculadas. |
CellValuePushed |
Usado para confirmar a entrada do
usuário em uma célula para a fone de dados no cache. Chame o método UpdateCellValue ao alterar um valor em uma fonte de dados em cache fora de um manipulador de eventos CellValuePushed para garantir que o valor atual será exibido no controle e para aplicar quaisquer modos de dimensionamento automáticos atualmente em vigor. |
NewRowNeeded | Usado para indicar a necessidade de uma nova linha na fonte de dados em cache. |
RowDirtyStateNeeded | Usado para determinar se uma linha possui qualquer alteração não confirmada. |
CancelRowEdit | Usado para indicar que uma linha deverá reverter as informações para o valores em cache. |
Nota: Você deverá também inicializar manualmente as colunas do controle.
Pegue o projeto completo aqui : DataGridView_VirtualMode.zip
Respondeu Jesus: O meu reino não é deste mundo; se o meu reino fosse deste
mundo, pelejariam os meus servos, para que eu não fosse entregue aos judeus; mas
agora o meu reino não é daqui.
João 18:36
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 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
https://msdn.microsoft.com/library/15a31akc%28v=vs.100%29.aspx
https://msdn.microsoft.com/pt-br/library/2b177d6d%28v=vs.100%29.aspx