Como garantir que vários controles associados à mesma fonte de dados permaneçam sincronizados
Geralmente, ao trabalhar com a associação de dados nos Windows Forms, vários controles são associados à mesma fonte de dados. Em alguns casos, pode ser necessário executar etapas extras para garantir que as propriedades associadas dos controles permaneçam sincronizadas entre si e com a fonte de dados. Essas etapas são necessárias em duas situações:
Se a fonte de dados não implementar IBindingListe, consequentemente, gerar eventos ListChanged do tipo ItemChanged.
Se a fonte de dados implementar IEditableObject.
No caso anterior, você pode usar um BindingSource para associar a fonte de dados aos controles. No último caso, você usa um BindingSource, manipula o evento BindingComplete e chama EndCurrentEdit no BindingManagerBaseassociado.
Exemplo
O exemplo de código a seguir demonstra como associar três controles — dois controles de caixa de texto e um controle de DataGridView — à mesma coluna em um DataSet usando um componente BindingSource. Este exemplo demonstra como manipular o evento BindingComplete e garantir que, quando o valor de texto de uma caixa de texto for alterado, a caixa de texto adicional e o controle DataGridView sejam atualizados com o valor correto.
O exemplo usa um BindingSource para associar a fonte de dados e os controles. Como alternativa, você pode associar os controles diretamente à fonte de dados e recuperar o BindingManagerBase para a associação do BindingContext do formulário e, em seguida, manipular o evento BindingComplete para o BindingManagerBase. Para obter um exemplo de como fazer isso, consulte a página Ajuda sobre o evento BindingComplete de BindingManagerBase.
// Declare the controls to be used.
private BindingSource bindingSource1;
private TextBox textBox1;
private TextBox textBox2;
private DataGridView dataGridView1;
private void InitializeControlsAndDataSource()
{
// Initialize the controls and set location, size and
// other basic properties.
this.dataGridView1 = new DataGridView();
this.bindingSource1 = new BindingSource();
this.textBox1 = new TextBox();
this.textBox2 = new TextBox();
this.dataGridView1.ColumnHeadersHeightSizeMode =
DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Dock = DockStyle.Top;
this.dataGridView1.Location = new Point(0, 0);
this.dataGridView1.Size = new Size(292, 150);
this.textBox1.Location = new Point(132, 156);
this.textBox1.Size = new Size(100, 20);
this.textBox2.Location = new Point(12, 156);
this.textBox2.Size = new Size(100, 20);
this.ClientSize = new Size(292, 266);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.dataGridView1);
// Declare the DataSet and add a table and column.
DataSet set1 = new DataSet();
set1.Tables.Add("Menu");
set1.Tables[0].Columns.Add("Beverages");
// Add some rows to the table.
set1.Tables[0].Rows.Add("coffee");
set1.Tables[0].Rows.Add("tea");
set1.Tables[0].Rows.Add("hot chocolate");
set1.Tables[0].Rows.Add("milk");
set1.Tables[0].Rows.Add("orange juice");
// Set the data source to the DataSet.
bindingSource1.DataSource = set1;
//Set the DataMember to the Menu table.
bindingSource1.DataMember = "Menu";
// Add the control data bindings.
dataGridView1.DataSource = bindingSource1;
textBox1.DataBindings.Add("Text", bindingSource1,
"Beverages", true, DataSourceUpdateMode.OnPropertyChanged);
textBox2.DataBindings.Add("Text", bindingSource1,
"Beverages", true, DataSourceUpdateMode.OnPropertyChanged);
bindingSource1.BindingComplete +=
new BindingCompleteEventHandler(bindingSource1_BindingComplete);
}
private void bindingSource1_BindingComplete(object sender, BindingCompleteEventArgs e)
{
// Check if the data source has been updated, and that no error has occurred.
if (e.BindingCompleteContext ==
BindingCompleteContext.DataSourceUpdate && e.Exception == null)
// If not, end the current edit.
e.Binding.BindingManagerBase.EndCurrentEdit();
}
' Declare the controls to be used.
Private WithEvents bindingSource1 As BindingSource
Private WithEvents textBox1 As TextBox
Private WithEvents textBox2 As TextBox
Private WithEvents dataGridView1 As DataGridView
Private Sub InitializeControlsAndDataSource()
' Initialize the controls and set location, size and
' other basic properties.
Me.dataGridView1 = New DataGridView()
Me.bindingSource1 = New BindingSource()
Me.textBox1 = New TextBox()
Me.textBox2 = New TextBox()
Me.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.dataGridView1.Dock = DockStyle.Top
Me.dataGridView1.Location = New Point(0, 0)
Me.dataGridView1.Size = New Size(292, 150)
Me.textBox1.Location = New Point(132, 156)
Me.textBox1.Size = New Size(100, 20)
Me.textBox2.Location = New Point(12, 156)
Me.textBox2.Size = New Size(100, 20)
Me.ClientSize = New Size(292, 266)
Me.Controls.Add(Me.textBox2)
Me.Controls.Add(Me.textBox1)
Me.Controls.Add(Me.dataGridView1)
' Declare the DataSet and add a table and column.
Dim set1 As New DataSet()
set1.Tables.Add("Menu")
set1.Tables(0).Columns.Add("Beverages")
' Add some rows to the table.
set1.Tables(0).Rows.Add("coffee")
set1.Tables(0).Rows.Add("tea")
set1.Tables(0).Rows.Add("hot chocolate")
set1.Tables(0).Rows.Add("milk")
set1.Tables(0).Rows.Add("orange juice")
' Set the data source to the DataSet.
bindingSource1.DataSource = set1
'Set the DataMember to the Menu table.
bindingSource1.DataMember = "Menu"
' Add the control data bindings.
dataGridView1.DataSource = bindingSource1
textBox1.DataBindings.Add("Text", bindingSource1, "Beverages", _
True, DataSourceUpdateMode.OnPropertyChanged)
textBox2.DataBindings.Add("Text", bindingSource1, "Beverages", _
True, DataSourceUpdateMode.OnPropertyChanged)
End Sub
Private Sub bindingSource1_BindingComplete(ByVal sender As Object, _
ByVal e As BindingCompleteEventArgs) Handles bindingSource1.BindingComplete
' Check if the data source has been updated, and that no error has occurred.
If e.BindingCompleteContext = BindingCompleteContext.DataSourceUpdate _
AndAlso e.Exception Is Nothing Then
' If not, end the current edit.
e.Binding.BindingManagerBase.EndCurrentEdit()
End If
End Sub
Compilando o código
Este exemplo de código requer
Referências aos conjuntos System, System.Windows.Formse System.Drawing.
Um formulário com o evento Load tratado e uma chamada para o método
InitializeControlsAndDataSource
no exemplo do manipulador de eventos Load do formulário.
Consulte também
.NET Desktop feedback