How to: Ensure Multiple Controls Bound to the Same Data Source Remain Synchronized

Oftentimes when working with data binding in Windows Forms, multiple controls are bound to the same data source. In some cases, it may be necessary to take extra steps to ensure that the bound properties of the controls remain synchronized with each other and the data source. These steps are necessary in two situations:

In the former case, you can use a BindingSource to bind the data source to the controls. In the latter case, you use a BindingSource and handle the BindingComplete event and call EndCurrentEdit on the associated BindingManagerBase.

Example

The following code example demonstrates how to bind three controls—two text-box controls and a DataGridView control—to the same column in a DataSet using a BindingSource component. This example demonstrates how to handle the BindingComplete event and ensure that when the text value of one text box is changed, the additional text box and the DataGridView control are updated with the correct value.

The example uses a BindingSource to bind the data source and the controls. Alternatively, you can bind the controls directly to the data source and retrieve the BindingManagerBase for the binding from the form's BindingContext and then handle the BindingComplete event for the BindingManagerBase. For an example of how to do this, see the Help page about the BindingComplete event of BindingManagerBase.

' 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 'InitializeControlsAndDataSource

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 occured.
    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

        // 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 occured.
            if (e.BindingCompleteContext == 
                BindingCompleteContext.DataSourceUpdate && e.Exception == null)

                // If not, end the current edit.
                e.Binding.BindingManagerBase.EndCurrentEdit();
        }

Compiling the Code

  • This code example requires

  • References to the System, System.Windows.Forms, and System.Drawing assemblies.

  • A form with the Load event handled and a call to the InitializeControlsAndDataSource method in the example from the form's Load event handler.

See Also

Tasks

How to: Share Bound Data Across Forms Using the BindingSource Component

Concepts

Change Notification in Windows Forms Data Binding

Interfaces Related to Data Binding

Other Resources

Windows Forms Data Binding