ADO.NET – Data Binding

por Leonardo Bruno Lima

Muitos programadores têm uma má impressão sobre vinculação de dados, muitos até com alguma razão. Tentarei nesse artigo desmistificar um pouco o uso de Data Binding utilizando o ADO.NET que em nada pode ser comparado com as tecnologias anteriores.

Qualquer objeto que herde a classe “control”, pode possuir um objeto BindingContext associado a ele, o Windows Forms por exemplo, possui pelo menos um BindingContext. O BindingContext gerencia os objetos que herdam de BindingManagerBase, que é uma classe abstrata. Esses objetos são o: CurrencyManager e o PropertyManager.

Esses objetos permitem a sincronização do data-bound control com a fonte de dados, por exemplo: um objeto TextBox que esteja vinculado a uma coluna de um DataTable, deve refletir sempre o valor corrente da coluna de acordo com a posição no registro.

O objeto CurrencyManager realiza essa sincronização mantendo um ponteiro para o item atual da lista ou registro. Quando algum item é modificado, o CurrencyManager deve notificar todos os controles vinculados para que eles atualizem os seus valores.

O objeto PropertyManager é usado para manter a sincronização de uma propriedade de um objeto com a propriedade de um data-bound control.

Usando o BindingContext podemos criar ou obter um desses dois objetos, de acordo com o Data Source. Por exemplo: Se o Data Source for um objeto que exponha apenas uma propriedade a ser vinculada, o BindingContext retornará um PropertyManager. Por outro lado, se o Data Source for um objeto que implemente as interfaces IList ou IBindingList por exemplo, o retorno será um CurrencyManager.

Cada Data Source associado a um controle de um Windows Form, possui um BindingManagerBase (CurrencyManager ou PropertyManager) associado, como mostra a figura abaixo:

Cc517967.DataBindingADO1(pt-br,MSDN.10).gif

É o objeto BindingContext que gerencia esses objetos no Windows Forms, identificando-os de acordo com o Data Source. A comunicação entre o BindingContext e um CurrencyManager específico é feita por Data Association. Por exemplo, se você precisa saber a posição de um registro que está sendo mostrado em um Data-bound control, basta obter um CurrencyManager através do DataBinding e verificar a propriedade Position.

Vamos fazer um exemplo utilizando alguns recursos de Data Binding.

Inicie um novo projeto Windows Application, chame-o de ADODataBinding e adicione os controles de acordo com a imagem e descrição abaixo:

Cc517967.DataBindingADO2(pt-br,MSDN.10).gif

Object

Propriedade

Valor

Textbox

Name

txtPrimeiroNome

 

Text

""

Textbox

Name

txtUltimoNome

 

Text

""

Textbox

Name

txtCargo

 

Text

""

Textbox

Name

txtNotas

 

MultiLine

True

 

Text

""

Button

Name

btnVoltar

 

Text

<

Button

Name

btnAvancar

 

Text

>

Label

Name

lblPosicao

 

Backcolor

Info

 

Text

""

 

TextAlign

MiddleCenter

Form

Name

FrmFuncionarios

 

Text

Funcionarios

 

Startup Position

CenterScreen

 

FormBorderStyle

FixedSingle

 

MaximizeBox

False

Vá em Server Explorer e crie uma nova conexão com o banco de dados Nothwind. Depois arraste a tabela de Funcionários para o formulário. Veja que automaticamente será criado um objeto OleDbConnection1 e OleDbDataAdapter1. Agora, clique com o botão direito em OleDbDataAdapter1 e escolha a opção Generate DataSet. Defina o nome do DataSet como dsNorthwind e clique em OK. Sua barra de componentes deverá ficar assim:

Cc517967.DataBindingADO3(pt-br,MSDN.10).gif

Agora vamos ao código:

No evento Load iremos preencher o DataSet, vincular os controles e definir um Event Handler 
para atulaização do Label com a posição do registro.

Private Sub FrmFuncionarios_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) 
Handles MyBase.Load
        '
        'Preenche o DataSet
        '
        Me.OleDbDataAdapter1.Fill(Me.DsNorthwind1)
        '
        'Vincula os controles
        '
        Me.txtPrimeiroNome.DataBindings.Add("Text", Me.DsNorthwind1.Funcionários, "Nome")
        Me.txtUltimoNome.DataBindings.Add("Text", Me.DsNorthwind1.Funcionários, "Sobrenome")
        Me.txtCargo.DataBindings.Add("Text", Me.DsNorthwind1.Funcionários, "Cargo")
        Me.txtNotas.DataBindings.Add("Text", Me.DsNorthwind1.Funcionários, "Observações")
        '
        'Adiciona os Handles para o evento Click
        '
        AddHandler Me.btnAvancar.Click, AddressOf Validação
        AddHandler Me.btnVoltar.Click, AddressOf Validação
        '
        AtualizaLabel()
        '
End Sub


Na sub de validação, teremos os tratamentos para uma correta navegação entre os registros:

Private Sub Validação(ByVal sender As System.Object, ByVal e As System.EventArgs)
'
'Obtem a quantidade de registros
'
RecordCount = Me.BindingContext(Me.DsNorthwind1.Funcionários).Count
'
'Obtem a posição atual
'
Position = Me.BindingContext(Me.DsNorthwind1.Funcionários).Position
'
'Verifica se existem registros
'
If RecordCount <= 1 Then
Me.btnAvancar.Enabled = False
Me.btnVoltar.Enabled = False
AtualizaLabel()
Exit Sub
End If
      '
      'Analisa de podemos voltar
      '
      If sender.Equals(Me.btnVoltar) Then
          If RecordCount > 1 Then
              Me.BindingContext(Me.DsNorthwind1.Funcionários).Position -= 1
          Else
              Me.btnVoltar.Enabled = False
          End If
      End If
      '
      'Analisa de podemos avançar
      '
      If sender.Equals(Me.btnAvancar) Then
          If RecordCount > Position Then
              Me.BindingContext(Me.DsNorthwind1.Funcionários).Position += 1
          Else
              Me.btnAvancar.Enabled = False
          End If
      End If
      '
      'Obtem a nova posição
      '
      Position = Me.BindingContext(Me.DsNorthwind1.Funcionários).Position + 1
      '
      'Recalcula os status dos botões de navegação
      '
      If RecordCount = Position Then
          btnAvancar.Enabled = False
      Else
          btnAvancar.Enabled = True
      End If

      If Position = 1 Then
          btnVoltar.Enabled = False
      Else
          btnVoltar.Enabled = True
      End If
      '
      'Atualiza o label que mostra a posição atual
      '
      AtualizaLabel()
      '
End Sub

E finalmente temos a sub que atualiza o Label com a informação da posição no registro:
Private Sub AtualizaLabel()
        RecordCount = Me.BindingContext(Me.DsNorthwind1.Funcionários).Count
        Position = Me.BindingContext(Me.DsNorthwind1.Funcionários).Position + 1

        If RecordCount <= 1 Then
            lblPosicao.Text = "Sem Registro"
        Else
            lblPosicao.Text = "Registro " & Position & " de " & RecordCount
        End If
End Sub

Conclusão: Com esse simples exemplo, podemos ver o quanto a vinculação de dados no .NET é poderosa. O que fizemos aqui poderia ter sido feito com a origem de dados sendo um simples arquivo texto ou um arquivo texto no formato XML, ou uma planilha do Excel, enfim, temos uma grande flexibilidade em relação à origem de dados.

Até a próxima.

Download

Fontes da aplicação exemplo
96 KB