.NET

12 dez, 2014

.NET – DataGridView 5 dicas essenciais (revisão VB.NET e C#)

Publicidade

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;
        }
    }
}

net_dgv11

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:

net_dgv12

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.

net_dgv13

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.

net_dgv14

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:

net_dgv15

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#.