C# - Usando Generics - Vinculando dados a um DataGridView (C#) - II


Na dica - Dica - Usando Generics - Vinculando dados a um DataGridView (C#) - eu mostrei como podemos usar Generics para vincular dados em um controle DataGridView em uma aplicação Windows Forms.

Hoje vamos incrementar nosso conhecimento sobre Generics mostrando como podemos obter uma lista genérica de objetos de um tipo a partir de um banco de dados SQL Server usando a linguagem C#.

Neste exemplo eu vou usar a nova versão do Visual Studio 2012 Express for desktop e o banco de dados Northwind.mdf onde vou criar uma tabela chamada Produtos com a seguinte estrutura:

O banco de dados Northwind.mdf foi copiado na minha máquina local na pasta c:\dados e possui a seguinte string de conexão:

Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\Northwind.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True

Vamos armazenar esta informação no arquivo de configuração da aplicação Windows Forms que iremos criar.

Abra o VS 2012 Express for desktop e clique em New Project, selecionando o template Windows Forms Application e informando o nome Generics_DataBase;

Vamos incluir uma classe Produto em nosso projeto que será o tipo a partir do qual iremos retornar a lista de objetos.

No menu PROJECT clique em Add Class e informe o nome Produto.cs. A seguir defina o seguinte código nesta classe:

namespace Generics_DataBase
{
   public class Produto
    {
        public string ID { get; set; }
        public string Nome { get; set; }
        public int Quantidade { get; set; }
        public double Preco { get; set; }
    }
}

Temos aqui uma classe POCO que define o tipo Produto contendo 3 propriedades : Nome, Quantidade e Preco;

Como nosso objetivo será obter uma lista genérica de Produtos a partir da tabela Produtos do banco de dados Northwind.mdf precisamos criar uma classe para acessar os dados e também precisamos definir um método na classe Produto para obtermos a lista de objetos Produtos.

No menu PROJECT clique em Add Class e informe o nome AcessoBD.cs. A seguir defina o seguinte código nesta classe:

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace Generics_DataGridView
{
    public static class AcessoBD
    {
        private static SqlConnection _sqlConnection;
        private static string _conConnectionString;
        
        public static void getConnection()
        {
            _conConnectionString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
            try
            {
                _sqlConnection = new SqlConnection(_conConnectionString);
                _sqlConnection.Open();
            }
            catch
            {
                throw new Exception();
            }
        }

        public static void CloseConnection()
        {
            try
            {
                if (_sqlConnection == null)
                {
                    _sqlConnection.Close();
                }
            }
            catch
            {
                throw new Exception();
            }
        }

        public static DataTable ExecuteQuery(string query)
        {
            getConnection();
            try
            {
                SqlDataAdapter adapter = new SqlDataAdapter(query, _sqlConnection);
                DataTable dt = new DataTable();
                adapter.Fill(dt);
                return dt;
            }
            catch
            {
                throw new Exception();
            }
            finally
            {
                if (_sqlConnection.State == ConnectionState.Open)
                    CloseConnection();
            }
        }
   }
}

Esta classe possui 3 métodos :

  1. getConnection - Abre uma conexão com o banco de dados SQL Server;
  2. CloseConnection - Fecha a conexão aberta;
  3. ExecuteQuery - Executa uma consulta SQL retornando um objeto DataTable;

Como a string de conexão esta sendo obtida a partir do arquivo de configuração App.Config vamos abrir este arquivo e incluir a informação da string de conexão do banco de dados Northwind:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <connectionStrings>
    <add name="conString"
        connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\Northwind.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True"
        providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Para que possamos acessar essa informação temos que incluir uma referência no projeto a System.Configuration. No menu PROJECT clique em Add Reference e selecione o item System.Configuration conforme figura abaixo e clique em OK;

Agora podemos concluir o código da classe Produto criando um método para retornar uma lista de objetos Produtos com o nome getProdutos com o seguinte código:

  public List<Produto> getProdutos()
        {
            List<Produto> listaProdutos = new List<Produto>();

            DataTable dtProdutos = AcessoBD.ExecuteQuery("Select * from Produtos");
            List<DataRow> drlist = new List<DataRow>();

            foreach (DataRow row in dtProdutos.Rows)
            {
                Produto produto = new Produto();
                produto.ID = row[0].ToString();
                produto.Nome = row[1].ToString();
                produto.Quantidade = Convert.ToInt32(row[2]);
                produto.Preco = Convert.ToDouble(row[3]);
                listaProdutos.Add(produto);
            }
            return listaProdutos;
        }

Basta agora definirmos a interface com o usuário usando o formulário form1.cs e incluindo no mesmo os seguintes controles:

No evento Click do botão btnExibir inclua o código abaixo:

 private void btnExibir_Click(object sender, EventArgs e)
 {
      Produto produtos = new Produto();
      dgvProdutos.DataSource = produtos.getProdutos();
  }

Executando o projeto teremos o seguinte resultado:

Que tal dar uma aparência mais agradável ao nosso DataGridView ?

Inclua a rotina formataGridViewPedido no formulário form1.cs com código abaixo:

   private void formataGridViewPedido()
        {
            var gdv = dgvProdutos;
            gdv.AutoGenerateColumns = false;
            gdv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
            gdv.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            //altera a cor das linhas alternadas no grid
            gdv.RowsDefaultCellStyle.BackColor = Color.White;
            gdv.AlternatingRowsDefaultCellStyle.BackColor = Color.Aquamarine;
            //altera o nome das colunas
            gdv.Columns[0].HeaderText = "Código";
            gdv.Columns[1].HeaderText = "Nome Produto";
            gdv.Columns[2].HeaderText = "Quantidade";
            gdv.Columns[3].HeaderText = "Preço Produto";
            //formata a coluna preço
            gdv.Columns[3].DefaultCellStyle.Format = "c";
            //seleciona a linha inteira
            gdv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            //não permite seleção de multiplas linhas
            gdv.MultiSelect = false;
            // exibe nulos formatados
            gdv.DefaultCellStyle.NullValue = " - ";
            //permite que o texto maior que célula não seja truncado
            gdv.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            //define o alinhamamento 
            gdv.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            gdv.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        }

Executando novamente o projeto teremos o seguinte resultado:

Bem melhor !!! não é mesmo ???

Pegue o projeto completo aqui: Generics_DataBase.zip

Gál 1:8 Mas, ainda que nós mesmos ou um anjo do céu vos pregasse outro evangelho além do que já vos pregamos, seja anátema.

Gál 1:9 Como antes temos dito, assim agora novamente o digo: Se alguém vos pregar outro evangelho além do que já recebestes, seja anátema.

Referências:


José Carlos Macoratti