 VB.NET - Sincronização automática com 
Mestre-Detalhe
 
VB.NET - Sincronização automática com 
Mestre-Detalhe
Este artigo aplica os conceitos sobre o databinding abordados nos artigos :
VB.NET - Desvendando os segredos do Data Binding no VB.NET II.
VB.NET - Lendo arquivos textos delimitados e preenchendo listas.
O gerenciador de banco de dados usado neste artigo é o MSDE onde usamos as tabelas Customers, Orders e Order Details do banco de dados é o Northwind que foi importado do MS Access conforme abordado nos artigos:
VB.NET - Preenchendo controles 
via MSDE
VB.NET - Criando uma conexão 
genérica para qualquer banco de dados. 
MSDE - Usando o MSDEQuery.
VB.NET - Criando banco de dados, 
tabelas, stored procedures e Views no MSDE   
Nota: o MSDE foi substituído pelo SQL Server Express que pode ser baixado em : SQL Server Express Edition download
O objetivo deste artigo é mostrar como você pode trabalhar com mais de uma tabela exibindo registros relacionados em uma estrutura Mestre-Detalhe usando o databinding. Vamos exibir os dados tabela Customers com seus dados relacionados na tabela Orders que por sua vez irá exibir os dados relacionados na tabela Orders Details.
Inicie um novo projeto no VS.NET e no formulário padrão insira os seguintes controles (conforme figura abaixo):
TextBox, GroupBox, Button, DataGrid

Ao executar o projeto o resultado será o exibido no formulário da figura abaixo:

Mas qual é mágica que estar por trás disto ? Como os registros são exibidos sincronizados usando uma estrutura do tipo Mestre-Detalhe ? Como conseguimos exibir os dados relacionados de 3 tabelas diferentes ?
Tratando os relacionamentos entre as tabelas com o DataRelation
Uma das funções primárias do objeto DataRelation é permitir a navegação de um DataTable para outro em um DataSet. Com isto estamos aptos a retornar todos os objetos DataRow relacionados em um DataTable usando um único DataRow de uma tabela relacionada. Assim depois de estabelecer um relacionamento entre a tabela Customers e a tabela Orders podemos retornar todos os registros de pedidos(orders) para um cliente(customer) particular usando o método DataRows.GetChildRows.
Se tivermos dois controles vinculados ao mesmo datasource, e não quisermos compartilhar a mesma posição , devemos estar certos de que o membro BindingContext de um controle difere do outro membro BindingContext do outro controle. Se ambos tiverem o mesmo BindingContext eles irão compartilhar a mesma posição no datasource.
Se incluímos uma Combobox e um DataGrid , como é o caso do nosso exemplo, em um formulário, o comportamento padrão é para que o membro BindingContext de cada um dos dois controles seja definido para o BindingContext do formulário. Assim , o comportamento padrão é para que o DataGrid e o Combobox compartilhem o mesmo BindingContext e dai a seleção na combobox estará sincronizada com a linha atual do DataGrid. Para não termos este comportamento devemos criar um novo membro BindingContext para um dos controles.
O código do projeto que cria os relacionamentos no DataSet entre as tabelas Customers, Orders e Orders Details é o seguinte :
|         'define o relacionamento entre as tabelas Customers e Orders
        Dim relCustOrd As System.Data.DataRelationDim colMestre As System.Data.DataColumn         Dim colDetalhe As System.Data.DataColumn
        colMestre = ds.Tables("Customers").Columns("CustomerID")        colDetalhe = ds.Tables("Orders").Columns("CustomerID")        relCustOrd = New System.Data.DataRelation("RelCustOrd", colMestre, colDetalhe)
        'inclui o relacionamento entre a tabela Customers e Orders no dataset
        ds.Relations.Add(relCustOrd)
        'define o relacionamento entre as tabelas Orders e Orders DetailsDim relOrdDet As System.Data.DataRelation Dim colMestre2 As System.Data.DataColumn         Dim colDetalhe2 As System.Data.DataColumn
        colMestre2 = ds.Tables("Orders").Columns("OrderID")        colDetalhe2 = ds.Tables("OrderDetails").Columns("OrderID")        relOrdDet = New System.Data.DataRelation("RelOrdDet", colMestre, colDetalhe2)
        'inclui o relacionamento entre a tabela Orders e Orders Details no dataset
        ds.Relations.Add(relOrdDet)
         ....... | 
Ele procurar reproduzir o relacionamento entre as tabelas:

Naturalmente o código que cria a conexão, o dataset já esta anteriormente definido conforme abaixo:
|        ConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind; _
                                  User ID=sa;password=;Data Source=MACORATI\VSDOTNET"
        Dim cn As SqlConnection = New SqlConnection(ConnectionString)        ds = New DataSet("CustOrders")
        Dim da1 As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers", cn)        da1.TableMappings.Add("Table", "Customers")        da1.Fill(ds)
        Dim da2 As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Orders", cn)        da2.TableMappings.Add("Table", "Orders")da2.Fill(ds)         Dim da3 As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM [Order Details]", cn)        da3.TableMappings.Add("Table", "OrderDetails")da3.Fill(ds) ....... | 
A seguir basta efetuar a vinculação dos dados com o DataGrid e a Combobox.
O exemplo exibe um DataGrid para 
os Pedidos (Orders) e outro para os detalhes(Orders Details). Os dados do 
cliente são exibidos em controles TextBox e Combobox.
Ao alterar o cliente selecionado os dados de cada DataGrid são atualizados e 
exibem os pedidos para o cliente atual. Afim de vincular os dois objetos 
DataGrids devemos definir o DataSource de cada DataGrid para o mesmo DataSet. 
Também devemos definir as propriedades do DataMembr para indicar o 
BindingContext com o qual eles estão relacionados. Fazemos isto definindo o 
DataMember para os DataGrids para o nome do relacionamento entre as tabelas
Customers e Orders; o mesmo é feito para a tabela
Orders e Orders Details.
| dsView = ds.DefaultViewManager 'vinculando as tabelas e seus relacionamentos dgPedidos.DataSource = dsView dgPedidos.DataMember = "Customers.RelCustOrd" dgDetalhesPedidos.DataSource = dsView dgDetalhesPedidos.DataMember = "Customers.RelCustOrd.RelOrdDet" 'vinculação da ComboBox cbNome.DataSource = dsView cbNome.DisplayMember = "Customers.CompanyName"         cbNome.ValueMember = "Customers.CustomerID"
         'vinculação dos TextBox        txtContato.DataBindings.Add("Text", dsView, "Customers.ContactName")        txtFone.DataBindings.Add("Text", dsView, "Customers.Phone")        txtFax.DataBindings.Add("Text", dsView, "Customers.Fax")
 | 
Para controlar a navegação definimos os códigos presentes no evento Click 
de cada um dos botões de comando:
 
| Private Sub btnAnterior_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnterior.Click If Me.BindingContext(dsView, "Customers").Position > 0 Then             System.Math.Max(System.Threading.Interlocked.Decrement(Me.BindingContext(dsView, "Customers").Position), _
                 Me.BindingContext(dsView, "Customers").Position + 1)End If End Sub | 
| Botão Anterior | 
| 
 Private Sub btnProximo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProximo.Click Dim cm As CurrencyManager = CType(Me.BindingContext(dsView, "Customers"), CurrencyManager) If cm.Position < cm.Count - 1 Then System.Math.Min(System.Threading.Interlocked.Increment(cm.Position), cm.Position - 1) End If End Sub 
 | 
| Botão Próximo | 
Com isto acabamos de mostrar como você conseguiu , sem muito esforço, tratar os dados de 3 tabelas relacionadas exibindo-os em uma estrutura Mestre-Detalhe sincronizada.
Use o seu talento e incremente a aplicação incluindo o tratamento de erros e outros detalhes...
Pegue o código completo do projeto 
aqui :  dbMestreDetalhe.zip
 
dbMestreDetalhe.zip
Eu sei é apenas VB.NET mas eu 
gosto ...
| 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 Facebook
  
 Compartilhe no Twitter
 
Compartilhe no Twitter
  
  
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
VB6 - DataGrid, MSFlexGrid e alguns conceitos básicos. - Macoratti.net
VB .NET - DataGridView - Selecionando e exibindo ... - Macoratti.net