C#Mestre Detalhes com DataGrid e DataGridView (revisão)


 Neste artigo eu vou mostrar como podemos exibir relacionamentos mestre-detalhes no DataGrid e no DataGridView usando a linguagem C#.

Podemos exibir dados relacionados, em uma visão mestre-detalhes, facilmente nos controles de grade como o DataGridView e no controle DataGrid.

Vamos exibir os dados relacionados entre duas tabelas :  Alunos e Notas no banco de dados Escola.mdb.

Veja abaixo a estrutura das tabelas:

Alunos Notas

Podemos ver que existe um relacionamento um-para-muitos entre as tabelas Alunos e Notas, onde um aluno possui uma ou mais notas.

Vamos usar esse relacionamento para exibir em uma grade a relação de alunos e, ao selecionar um aluno, veremos suas respectivas notas.

Vamos usar o provedor OleDb para acessar os dados e criar os objetos DataAdapter, DataSet e DataRelation da ADO .NET.

Vamos exibir esse relacionamento mestre-detalhes nos controles DataGrid e no DataGridView.

Recursos usados:

Criando a solução no VS 2015 Community

Abra o VS Community 2015 e crie um projeto do tipo Windows Forms Application usando a linguagem C#, com o nome Mestre-Detalhes.

Vamos incluir um novo formulário no projeto via menu Project -> Add Windows Forms aceitando o nome Form2.cs.

Assim temos dois formulários que iremos usar.

1- Exibindo mestre-detalhes usando o DataGrid

No formulário Form1.cs inclua um controle DataGrid com o nome dgAlunos conforme o leiaute abaixo:

A seguir inclua os namespaces neste formulário :

using System;
using System.Data;
using System.Windows.Forms;

A seguir vamos definir três variáveis no início do formulário:  dois adapters e um dataset:

// Data adapters para carregar dados
private OleDbDataAdapter DaAlunos, DaNotas;
   
// O DataSet para manipular os dados
private DataSet AlunosDataSet;

Neste código acima declaramos dois objetos OleDbDataAdapter: DaAlunos e DaNotas, para carregar os dados das tabelas Alunos e Notas.

Declaramos também o DataSet  AlunosDataSet para tratar os dados quando eles estiverem carregados na memória.

No evento Load do formulário temos a rotina que carrega as tabelas, define o relacionamento entre as tabelas e exibe os dados no DataGrid:

        // Carregando os dados
        private void Form1_Load(object sender, EventArgs e)
        {
            // Definindo a string de conexão
            string connect_string =
                "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Escola.mdb;Mode=Share Deny None";
            // Criando dum DataAdapter para carregar a tabela Alunos
            DaAlunos = new OleDbDataAdapter("SELECT * FROM Alunos", connect_string);
            // Criando um DataAdapter para carregar a tabela Notas
            DaNotas = new OleDbDataAdapter("SELECT * FROM Notas", connect_string);
            // Cria e preenche o DataSet.
            AlunosDataSet = new DataSet();
            DaAlunos.Fill(AlunosDataSet, "Alunos");
            DaNotas.Fill(AlunosDataSet, "Notas");
            // Define o relacionamento entre as tabelas
            DataRelation data_relation = new DataRelation(
                "Alunos_Notas",
                AlunosDataSet.Tables["Alunos"].Columns["AlunoId"],
                AlunosDataSet.Tables["Notas"].Columns["AlunoId"]);
                AlunosDataSet.Relations.Add(data_relation);
            // Vincula os dados Grid com o DataSet.
            dgAlunos.DataSource = AlunosDataSet;
      }

No código acima definimos a string de conexão com o banco Escola.mdb e criamos dois data adatper onde usamos consultas SQL para obter os dados das respectivas tabelas.

Criamos um novo DataSet e usamos os data adapters para copiar os dados do banco de dados no DataSet.

A seguir definimos o relacionamento mestre detalhes entre as tabelas Alunos e Notas no DataSet onde o primeiro parâmetro do construtor é o nome do relacionamento e os outros dois parâmetros indica as colunas que estão relacionadas.

Após criar o relacionamento precisamos incluí-lo na coleção de relacionamentos do DataSet.

E exibimos os dados no DataGrid:

Executando o projeto neste momento teremos o seguinte resultado:

1- Clicando no sinal de mais da coluna veremos dois links no DataGrid: Alunos e Notas

2- Clicando no link Alunos veremos os dados dos alunos. Para ver as notas de um aluno clique no sinal de mais no início da linha para exibir o link do relacionamento:

3- Clicando no link Alunos_Notas veremos as notas do aluno selecionado. Note que podemos retornar a visão dos dados do aluno clicando na set superior à direita:

Esse é um comportamento típico do DataGrid que foi substituído pelo DataGridView.

2- Exibindo mestre-detalhes usando o DataGridView

Vamos agora exibir os dados no DataGridView e para isso vamos precisar de dois controles :  um para os Alunos e outro para as Notas:

Para isso inclua um controle no formulário Form2.cs com o nome dgvAlunos e outro controle dgvNotas. Inclua também um controle MenuStrip com o texto Alunos, conforme o leiaute abaixo:

Vamos agora copiar o código que usamos no DataGrid para o formulário Form2.cs:

Veja como ficou o código do evento Load:

        private void Form2_Load(object sender, EventArgs e)
        {
            // Definindo a string de conexão
            string connect_string =
                "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Escola.mdb;Mode=Share Deny None";
            // Criano dum DataAdapter para carregar a tabela Alunos
            DaAlunos = new OleDbDataAdapter("SELECT * FROM Alunos", connect_string);
            // Criando um DataAdapter para carregar a tabela Notas
            DaNotas = new OleDbDataAdapter("SELECT * FROM Notas", connect_string);
            // Cria e preenche o DataSet.
            AlunosDataSet = new DataSet();
            DaAlunos.Fill(AlunosDataSet, "Alunos");
            DaNotas.Fill(AlunosDataSet, "Notas");
            // Define o relacionamento entre as tabelas
            DataRelation data_relation = new DataRelation(
                "Alunos_Notas",
                AlunosDataSet.Tables["Alunos"].Columns["AlunoId"],
                AlunosDataSet.Tables["Notas"].Columns["AlunoId"]);
            AlunosDataSet.Relations.Add(data_relation);
            
            //faz a vinculação entre os Grids usando o BindingSource
            //define o bindingsource bsAluno
            BindingSource bsAluno = new BindingSource();
            bsAluno.DataSource = AlunosDataSet;
            bsAluno.DataMember = "Alunos";
            
            //define o bindingsource bsNota e vincula com o bsAluno
            BindingSource bsNota = new BindingSource();
            bsNota.DataSource = bsAluno;
            bsNota.DataMember = "Alunos_Notas"; 
            // Vincula os dados Grid com o DataSet.
            dgvAlunos.DataSource = bsAluno;
            dgvNotas.DataSource = bsNota;  
       }

O código é praticamente o mesmo. O código destacado em azul é o que tivemos que incluir para definir o relacionamento entre os dados das duas tabelas e os respectivos DataGrdiView de forma que ao clicar em uma linha no grid com os dados dos alunos selecionando um aluno veremos as notas deste aluno no outro grid.

Executando o projeto teremos:

Para salvar os dados nas tabelas do banco de dados, se os mesmos forem alterados no DataGrid ou DataGridView, inclua o código abaixo no evento Closing do formulário Form1 e Form2:

        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Usamos um CommandBuilder para os comandos INSERT, UPDATE, e DELETE 
            OleDbCommandBuilder cmdblder_alunos = new OleDbCommandBuilder(DaAlunos);
            OleDbCommandBuilder cmdblder_notas = new OleDbCommandBuilder(DaNotas);
            // Atualiza o banco de dados
            try
            {
                DaAlunos.Update(AlunosDataSet, "Alunos");
                DaNotas.Update(AlunosDataSet, "Notas");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Aqui criamos dois objetos OleDbCommandBuilder para cada tabela. Esses objetos geram automaticamente os comandos SQL Insert, Update e Delete para salvar as alterações nos dados.

A seguir, os comandos são associados com o DataAdatpers passados no construtor de cada Builder.

Pegue o projeto completo aqui :   Mestre_Detalhes_Grid.zip

"Porque pela graça sois salvos, por meio da fé; e isto não vem de vós, é dom de Deus.
Não vem das obras, para que ninguém se glorie;"

Efésios 2:8,9

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 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?


  Gostou
?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti