Neste artigo eu vou fazer uma revisão dos conceitos usados em alguns recursos do controle DataGridView na linguagem VB .NET e C#.
O DataGridView é um o controle que lhe dá a capacidade de personalizar e editar dados tabulares em projetos Windows Forms. Este componente oferece diversas propriedades, métodos e eventos para personalizar sua aparência e comportamento. Neste artigo, vamos discutir algumas perguntas frequentes e suas soluções.
Recursos usados:
- Microsoft Visual Studio 2013 Express for web / Microsoft Visual Studio 2013 Express for windows desktop
- SQL Server Express 2012
1. Preenchendo um DataGridView a partir de um banco de dados
Para preencher um DataGridView a partir de um banco de dados, basta selecionar a tabela, efetuar a conexão com a fonte de dados e retornar os dados para exibição. Isso pode ser feito assim:
- Exemplo: Banco de dados Northwind.mdf do SQL Server, tabela Orders
- Projeto Windows Forms: DataGridView – dgvDados , Button : btnPreencher
- A forma mais comum (não a mais correta): colocar o código de acesso a dados no formulário
using System; using System.Data; using System.Data.SqlClient; using System.Windows.Forms; namespace DataGridView_revisao { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private SqlDataAdapter da; private SqlConnection conn; BindingSource bsource = new BindingSource(); DataSet ds = null; string sql; private void btnPreencher_Click(object sender, EventArgs e) { CarregarDados(); } private void CarregarDados() { string connectionString = @"Data Source=(LocalDB)\v11.0;Initial Catalog=Northwind;Integrated Security=True"; conn = new SqlConnection(connectionString); sql = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, Freight, ShipName, ShipCountry FROM Orders"; da = new SqlDataAdapter(sql, conn); conn.Open(); ds = new DataSet(); SqlCommandBuilder commandBuilder = new SqlCommandBuilder(da); da.Fill(ds, "Orders"); bsource.DataSource = ds.Tables["Orders"]; dgvDados.DataSource = bsource; } } }
O exemplo cria um Dataset, que é preenchido por um DataAdapter usando a tabela Orders. A vinculação é feita usando um o controle BindingSource.
A versão VB .NET do mesmo código:
Imports System Imports System.Data Imports System.Data.SqlClient Imports System.Windows.Forms Private da As SqlDataAdapter Private conn As SqlConnection Private bsource As New BindingSource() Private ds As DataSet = Nothing Private sql As String Private Sub btnPreencher_Click(ByVal sender As Object, ByVal e As EventArgs) CarregarDados() End Sub Private Sub CarregarDados() Dim connectionString As String = "Data Source=(LocalDB)\v11.0;Initial Catalog=Northwind;Integrated Security=True" conn = New SqlConnection(connectionString) sql = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, Freight, ShipName, ShipCountry FROM Orders" da = New SqlDataAdapter(sql, conn) conn.Open() ds = New DataSet() Dim commandBuilder As New SqlCommandBuilder(da) da.Fill(ds, "Orders") bsource.DataSource = ds.Tables("Orders") dgvDados.DataSource = bsource End Sub
A string de conexão poderia ter sido colocada no arquivo de configuração da aplicação.
2. Atualizar os dados no DataGridView e salvar as alterações no banco de dados
Após editar os dados diretamente no controle DataGridView – dgvDados – para salvar as alterações no banco de dados, utilize o seguinte código em um evento Click de um botão de comando – btnSalvar:
C#
private void btnSalvar_Click(object sender, EventArgs e) { try { DataTable dt = ds.Tables["Orders"]; this.dgvDados.BindingContext[dt].EndCurrentEdit(); this.da.Update(dt); MessageBox.Show("Banco de dados Atualizado com sucesso", "Atualizado", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch(Exception ex) { MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Visual Basic .NET
Private Sub btnSalvar_Click(sender As Object, e As EventArgs) Handles btnSalvar.Click Try Dim dt As DataTable = ds.Tables("Orders") Me.dgvDados.BindingContext(dt).EndCurrentEdit() Me.da.Update(dt) MessageBox.Show("Banco de dados Atualizado com sucesso", "Atualizado", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As Exception MessageBox.Show("Erro : " & ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub
Lembre-se que não estamos efetuando uma validação para a entrada dos dados.
3. Exibir uma mensagem de confirmação antes de deletar uma linha em um DataGridView
Para deletar uma linha do DataGridView- dgvDados – que representa um registro na tabela Orders, basta selecionar a linha e pressionar a tecla Delete. Para solicitar uma confirmação ao usuário desta ação, vamos usar o evento UserDeletingRow para exibir uma mensagem solicitando ao usuário que confirme ou não a operação. Se o usuário cancelar a operação, vamos definir e.Cancel como true e cancelar a operação.
C#
private void dgvDados_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) { if (!e.Row.IsNewRow) { DialogResult res = MessageBox.Show("Tem certeza de que deseja deletar esta linha ?", "Deletar ?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (res == DialogResult.No) e.Cancel = true; } }
Visual Basic .NET
Private Sub dgvDados_UserDeletingRow(sender As Object, e As DataGridViewRowCancelEventArgs) Handles dgvDados.UserDeletingRow If Not e.Row.IsNewRow Then Dim res As DialogResult = MessageBox.Show("Tem certeza de que deseja deletar esta linha ?", "Deletar ?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) If res = Windows.Forms.DialogResult.No Then e.Cancel = True End If End If End Sub
Após deletar a linha para atualizar o banco de dados, você deve clicar no botão para salvar as alterações. Mas atenção! Se a linha que você estiver deletando possuir ou fazer parte de uma referência com outra tabela ao tentar atualizar o banco de dados, você vai receber uma mensagem de restrição de referência (REFERENCE constraint) e não será possível atualizar o banco de dados.
4. Realizar a validação dos dados em uma célula específica do DataGridView
Para realizar a validação dos dados em uma célula específica você tem que identificar à qual coluna da tabela a célula está vinculada e definir a validação.
No nosso exemplo vamos validar a edição de dados para a coluna ShipCountry, não permitindo que esta célula esteja em branco. O nosso exemplo o nome da coluna no DataGridView corresponde ao nome da coluna da tabela (fique atento a esse detalhe).
Para realizar a validação usamos dois eventos do controle DataGridView:
- CellValidating – Este evento ocorre quando o conteúdo da célula atual muda e é usado para realizar a validação para a coluna especificada na célula do Datagridview, exibindo uma mensagem de erro na linha do DataGridView que contém a coluna validada;
- CellEndEdit – Permite limpar o erro da linha do DatagridView se o usuário pressionar a tecla ESC.
O evento CellValidating validando a célula cujo HeaderText é igual a ShipCountry:
C#
private void dgvDados_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) { string headerText =dgvDados.Columns[e.ColumnIndex].HeaderText; // Aborta a validação se a célula não for a coluna ShipCountry if (!headerText.Equals("ShipCountry")) return; // Confirma que a célula não pode estar vazia if (string.IsNullOrEmpty(e.FormattedValue.ToString())) { dgvDados.Rows[e.RowIndex].ErrorText ="O nome do país de destino não pode estar em branco"; e.Cancel = true; } }
Visual Basic .NET
Private Sub dgvDados_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles dgvDados.CellValidating Dim headerText As String = dgvDados.Columns(e.ColumnIndex).HeaderText ' Aborta a validação se a célula não for a coluna ShipCountry If Not headerText.Equals("ShipCountry") Then Return ' Confirma que a célula não pode estar vazia If (String.IsNullOrEmpty(e.FormattedValue.ToString())) Then dgvDados.Rows(e.RowIndex).ErrorText = "O nome do país de destino não pode ser em branco" e.Cancel = True End If End Sub
O evento CellEndEdit limpará o erro da linha e retorna os dados na célula se o usuário pressionar a tecla ESC:
C#
private void dgvDados_CellEndEdit(object sender, DataGridViewCellEventArgs e) { //limpa o erro da linha se o usuário pressionar ESC dgvDados.Rows[e.RowIndex].ErrorText = String.Empty; }
Visual Basic .NET
Private Sub dgvDados_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles dgvDados.CellEndEdit 'limpa o erro da linha se o usuário pressionar ESC dgvDados.Rows(e.RowIndex).ErrorText = String.Empty End Sub
Onde dgvDados é o nome do controle DataGridView. A Rows é a coleção de linha e [e.RowIndex] é o índice que identifica a linha atual.
5. Calcular o valor total de uma coluna do DataGridView e exibir o resultado em um TextBox:
Podemos calcular o valor total de uma coluna do datagridview que possua valores monetários ou valores numéricos exibindo o resultado em um controle TextBox. No nosso exemplo, vamos calcular o valor total da coluna Freight exibindo o valor formatado em um controle TextBox – txtValorTotal.
Vamos usar um botão de comando – btnCalcularValorTotal – e incluir o código no seu evento Click e criar um método chamado CalcularValorTotal() que realiza o cálculo:
O código do evento Click do botão btnCalcularValorTotal:
C#
private void btnCalcularValorTotal_Click(object sender, EventArgs e) { if (dgvDados.Rows.Count > 0) txtValorTotal.Text = CalcularValorTotal().ToString("c"); }
Visual Basic .NET
Private Sub btnCalcularValorTotal_Click(sender As Object, e As EventArgs) Handles btnCalcularValorTotal.Click If dgvDados.Rows.Count > 0 Then txtValorTotal.Text = CalcularValorTotal().ToString("c") End If End Sub
O código do método CalcularValorTotal:
C#
private double CalcularValorTotal() { double total = 0; int i = 0; for (i = 0; i < dgvDados.Rows.Count; i++) { total = total + Convert.ToDouble(dgvDados.Rows[i].Cells["Freight"].Value); } return total; }
Visual Basic .NET
Private Function CalcularValorTotal() As Double Dim total As Double = 0 Dim i As Integer = 0 For i = 0 To dgvDados.Rows.Count - 1 total = total + Convert.ToDouble(dgvDados.Rows(i).Cells("Freight").Value) Next i Return total End Function
Atente para o fato que eu não estou realizando um tratamento de erro no cálculo do valor e isso seria recomendável (use um bloco try/catch).
Eu não diria que os recursos do DataGridView são ilimitados, mas que ele tem recursos pra caramba tem! E neste artigo eu mostrei 5 dicas essenciais para usar o DataGridVIew com VB .NET e C#.
- Pegue os projetos aqui: DataGridViewe_Revisao_VBNET.zip e DataGridView_revisao_CSharp.zip
- Veja também vídeo aula para este artigo em: VB .NET – Paginação de dados no DataGridView com DataSet