C# - CRUD com TreeView e DataGridView


Vamos realizar as operações básicas de acesso e manutenção de dados via ADO .NET em um banco de dados SQL Server usando os controles TreeView e DataGridView.

Na verdade os controles serão usados apenas para exibirmos as informações da tabela Alunos do banco de dados Cadastro.mdf.

Vamos exibir os nomes dos alunos no controle TreeView e os detalhes no controle DataGridView de forma que ao selecionar um nome no controle TreeView as informações serão exibidas em controles TextBox no formulário e estarão prontas para serem atualizadas ou excluídas.

É um projeto simples que mostra de forma básica como acessar e realizar as operações CRUD em uma aplicação C#.

Definindo o banco de dados e a tabela

O banco de dados Cadastro.mdf e a tabela Alunos podem ser criados diretamente no SQL Server Management Studio com a seguinte estrutura :

A tabela Alunos possui os seguintes campos:
  • id
  • nome
  • email
  • idade
  • endereco
  • ativo     

ou usando o script a seguir:

1- Script para o banco de dados Cadastro.mdf ser criado na pasta c:\dados

USE [master]
GO
CREATE DATABASE [Cadastro] ON  PRIMARY
( NAME = N'Cadastro', FILENAME = N'c:\dados\Cadastro.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON
( NAME = N'Cadastro_log', FILENAME = N'c:\dados\Cadastro_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

Se você for usar script acima atente para o fato que o local de criação do banco de dados será na pasta c:\dados . Portanto você deve alterar a pasta para o seu local preferido.

2- Script para criar a tabela Alunos

USE [Cadastro]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Alunos](
[id] [int] IDENTITY(1,1) NOT NULL,
[nome] [nvarchar](50) NULL,
[email] [nvarchar](150) NULL,
[idade] [int] NULL,
[endereco] [nvarchar](150) NULL,
[ativo] [bit] NULL,
 CONSTRAINT [PK_Alunos] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Criando o projeto no Visual C# 2010 Express Edition

Abra o Visual C# 2010 Express Edition e crie um novo projeto no menu File-> New Project escolhendo o template Windows Forms Application com o nome UsandoTreeView e clique no botão OK;

A seguir no formulário form1.cs inclua os controles : TreeView (tvwAlunos) , DataGridView(gdvDetalhes), 5 TextBox , 1 CheckBox(chkAtivo) e 4 Buttons conforme o leiaute da figura abaixo:

Controles do formulário form1.cs:

- TextBox :

  • txtCodigo
  • txtNome
  • txtEndereco
  • txtEmail
  • txtIdade
  • ChkAtivo

- Button :

  • btnLimpar
  • btnNovo
  • btnAtualizar
  • btnDeletar

Agora vamos definir uma string de conexão no arquivo App.Config. Para criar o arquivo de configuração no menu Project clique em Add New Item e a seguir selecione o template Application Configuration FIle e aceite o nome padrão clicando em Add;

A seguir defina a string de conexão conforme mostra a figura abaixo onde iremos acessar o banco de dados Cadastro.mdf do SQL Server;

Para podermos acessar o arquivo de configuração e obter a string de conexão definida temos que incluir uma referência a System.Configuration via menu Project clicando em Add Reference e na tab .NET selecionar o item desejado e clicar em OK;

Temos também de definir no formulário form1.cs seguintes namespaces:

using System;

using System.Data;

using System.Windows.Forms;

using System.Data.SqlClient;

using System.Configuration;

Definindo o código 

Agora vamos definir o código da aplicação e antes de prosseguir quero deixar claro que:

Definindo as variáveis usadas no projeto no início do formulário:

    static bool incluir = false;
    static string strConexaoSQL = ConfigurationManager.ConnectionStrings["conexaoSQL_Cadastro"].ToString();
    SqlDataReader dr;
   SqlConnection conn = new SqlConnection(strConexaoSQL);

Definindo a rotina  carregaDadosTreeView para carregar o controle TreeView para exibir o nome dos alunos da tabela Alunos:

        /// <summary>
        /// Carrega dados no TreeView
        /// </summary>
        private void carregaDadosTreeView()
        {
            tvwAlunos.Nodes.Clear();
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("SELECT nome FROM alunos", conn);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    tvwAlunos.Nodes.Add(dr.GetValue(0).ToString());
                }
                dr.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                conn.Close();
            }
        }

Rotina carregaDadosGridView para carregar os dados da tabela Alunos no controle DataGridView

         /// <summary>
        /// Carrega dados no GridView
        /// </summary>
        private void carregaDadosGridView()
        {
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("SELECT * FROM Alunos", conn);
                DataSet ds = new DataSet();
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(ds);
                gdvDetalhes.DataSource = ds.Tables[0];
                dr.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                conn.Close();
            }
        }

Rotina Vincula() que chama as duas rotinas acima:

       /// <summary>
        /// Vincula os dados no TreeView e GridView
        /// </summary>
        private void vincula()
        {
            carregaDadosTreeView();
            carregaDadosGridView();
        }

 

Código do evento Load do formulário que chama a rotina vincula():

       /// <summary>
        /// Chama a rotina para vincular os dados no 
        /// TreeView e DataGridView
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            vincula();
        }

A rotina carregaDados() usada para exibir os dados do aluno selecionado no controle TreeView nos controles TextBox:

        /// <summary>
        /// Carrega os dados a partir da tabela Alunos pelo nome
        /// </summary>
        /// <param name="nome"></param>
        private void carregaDados(string nome)
        {
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("SELECT * FROM alunos where nome = '" + nome +"'" , conn);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    txtCodigo.Text = dr["id"].ToString();
                    txtNome.Text = dr["nome"].ToString();
                    txtEndereco.Text = dr["endereco"].ToString();
                    txtEmail.Text = dr["email"].ToString();
                    txtIdade.Text = dr["idade"].ToString();
                    chkAtivo.Checked = (Convert.ToBoolean(dr["ativo"]) == true ? true : false);
                }
                dr.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                conn.Close();
            }
        }

Código do evento AfterSelect do controle TreeView que chama a rotina carregaDados quando um nó do controle for selecionado;

Isso feito obtendo o nome do Nó selecionado usando o método SelectedNode e chamando a rotina para obter as informação pelo nome obtido:

            string strNome = this.tvwAlunos.SelectedNode.Text.ToString();

A variável incluir é definida como false de forma que a inclusão não será possível até que seu valor seja true;

  /// <summary>
        /// Após selecionar um item no TreeView
        /// chama a rotina para preencher os textbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tvwAlunos_AfterSelect(object sender, TreeViewEventArgs e)
        {
            incluir = false;
            string strNome = this.tvwAlunos.SelectedNode.Text.ToString();
            carregaDados(strNome);
        }

 

O código definido acima faz com que quando a aplicação for iniciada os controles TreeView e DataGridView seja preenchidos com os dados da tabela Alunos conforme  mostra  a figura abaixo:

Realizando a manutenção dos dados

Vamos agora definir o código para alterar, incluir e excluir dados da tabela Alunos. Faremos isso diretamente no formulário usando o evento Click de cada um dos botões de comando.

Utilizaremos instruções SQL no formato texto , o que não é muito aconselhável por permitir a injeção SQL. O mais indicado seria utilizar stored procedures , mas mostrarei isso em outro artigo.

As instruções SQL usadas são:

Estamos usando o método ExecuteNonQuery do objeto Command para executar as instruções SQL. Ele não retorna nenhum registro.

1- Código do evento Click do botão Limpar que chama a rotina limpaControles e põe o foco no controle txtNome:

 private void btnLimpar_Click(object sender, EventArgs e)
 {
            limpaControles();
            txtNome.Focus();
            incluir = true;
 }

Rotina limpaControles() usada para limpar os controles TextBox e CheckBox do formulário:

 /// <summary>
        /// Limpa os controles TextBox e checkbox 
        /// do container GroupBox
        /// </summary>
        private void limpaControles()
        {
            foreach (Control ctrl in grpAlunos.Controls)
            {
                if (ctrl is TextBox)
                {
                    ((TextBox)ctrl).Clear();
                }
                if (ctrl is CheckBox)
                {
                    ((CheckBox)ctrl).Checked = false;
                }
            }
        }

2- Código do evento Click do botão Novo que usa a instrução SQL INSERT INTO para incluir dados na tabela Alunos:

        /// <summary>
        /// Incluir um novo registro na tabela Alunos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNovo_Click(object sender, EventArgs e)
        {
            if (incluir)
            {
                if ((txtNome.Text != string.Empty) && (txtEmail.Text != string.Empty) && (txtEndereco.Text != string.Empty))
                {
                    try
                    {
                        conn.Open();
                        int valor = chkAtivo.Checked == true ? 1 : 0;
                        string sql = "Insert Into Alunos Values(" + "'" + txtNome.Text + "','" + txtEmail.Text + "'," + txtIdade.Text + ",'" + txtEndereco.Text + "'," + valor + ");";
                        SqlCommand cmd = new SqlCommand(sql, conn);
                        cmd.ExecuteNonQuery();
                        MessageBox.Show("Registro incluído na tabela Alunos.");
                        conn.Close();
                        vincula();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                    finally
                    {
                        conn.Close();
                        incluir = false;
                    }
                }
                else
                {
                    MessageBox.Show("Valores inválidos.");
                }
            }
            else
            {
                incluir = false;
                MessageBox.Show("Limpe os controles e informe novos valores para incluir um registro.");
            }
        }

3- Código do evento Click do botão Atualizar que usa a instrução SQL UPDATE SET para incluir dados na tabela Alunos:

  /// <summary>
        /// Atualiza os dados da tabela Alunos pelo 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAtualizar_Click(object sender, EventArgs e)
        {
            if ((txtCodigo.Text != string.Empty) && (txtNome.Text != string.Empty))
            {
                try
                {
                    conn.Open();
                    int valor = chkAtivo.Checked == true ? 1 : 0;
                    string sql = "update Alunos set nome = '" + txtNome.Text + "', email = '" + txtEmail.Text + "', idade = " + txtIdade.Text + ", endereco = '" + txtEndereco.Text + "', ativo = " + valor + ";";
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.ExecuteNonQuery();
                    MessageBox.Show("Registros atualizados na tabela Alunos.");
                    conn.Close();
                    vincula();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    conn.Close();
                }
            }
            else
            {
                MessageBox.Show("Preencha os dados do Aluno.");
            }
        }

4- Código do evento Click do botão Deletar que usa a instrução SQL DELETE FROM para excluir dados na tabela Alunos:

        /// <summary>
        /// Deleta os registros da tabela alunos pelo código do aluno
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDeletar_Click(object sender, EventArgs e)
        {
            if (txtCodigo.Text != string.Empty)
            {
                try
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand("DELETE FROM Alunos WHERE id=" + Convert.ToInt32(txtCodigo.Text) + ";", conn);
                    cmd.ExecuteNonQuery();
                    MessageBox.Show("Registro excluído com sucesso.");
                    conn.Close();
                    vincula();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    conn.Close();
                }
            }
            else
            {
                MessageBox.Show("Informe o código do aluno.");
            }
        }

Destaques do código:

Estamos usando a instrução try/Catch/Finally para realizar o tratamento de exceções nas rotinas. O bloco try-catch-finally é usado para envolver o código onde existe a possibilidade de uma exceção/erro ocorrer. Um bloco try-catch-finally é constituído das seguintes seções :

  1. O código que pode gerar uma exceção é colocando dentro do bloco try
  2. Se o erro/exceção ocorrer o bloco catch entra em ação e o você faz o tratamento do erro
  3. Dentro do bloco finally você coloca o código que deverá ser executado sempre quer ocorra ou não a exceção.

O operador ternário esta sendo usado para avaliar se o controle CheckBox esta ou não marcado.

int valor = chkAtivo.Checked == true ? 1 : 0;

o "?" funciona como um if :

No exemplo, como o campo da tabela para armazenar este valor é do tipo bit devemos gravar o valor zero (0) (false) ou um (1) (true).

Para concluir temos o código que usamos para validar a entrada de dados nos controles TextBox do formulário:

1- Aceita somente números e backspace para a idade : txtIdade

  private void txtIdade_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!Char.IsDigit(e.KeyChar) && e.KeyChar != (char)8)
                e.Handled = true;
        }

1- Aceita somente alfanuméricos e backspace para o email e o endereço : txtEmail e txtEndeco

       private void txtNome_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Char.IsDigit(e.KeyChar) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }
       private void txtEndereco_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Char.IsDigit(e.KeyChar) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

Dessa forma temos uma aplicação simples que permite realizar operações CRUD em um banco de dados SQL Server. Todo o código foi mostrado e as orientações estão detalhadas para você reproduzir o projeto.

O projeto completo esta no Super DVD .NET e no Super CD .NET

"E, se alguém ouvir as minhas palavras, e não crer, eu não o julgo: porque eu vim, não para julgar o mundo, mas para salvar o mundo." João 12:47

Referências:


José Carlos Macoratti