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:
É 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:
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:
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.