HOW TO:確保繫結至相同資料來源的多個控制項都能保持同步
更新:2007 年 11 月
在 Windows Form 中使用資料繫結 (Data Binding) 時,經常都會將多個控制項繫結到相同的資料來源。在某些情況下必須採取額外的步驟,以確保控制項的繫結屬性會與彼此和資料來源維持同步。遇到下面兩種情況時,必須採取這些步驟:
如果資料來源沒有實作 IBindingList,並因此產生 ItemChanged 型別的 ListChanged 事件。
如果資料來源有實作 IEditableObject。
在第一種情況下,您可以使用 BindingSource 將資料來源繫結到控制項。在第二種情況下,則是可以使用 BindingSource 並處理 BindingComplete 事件,以及呼叫關聯之 BindingManagerBase 上的 EndCurrentEdit。
範例
下列程式碼範例示範如何使用 BindingSource 元件,將三個控制項 (兩個文字方塊控制項和一個 DataGridView 控制項) 繫結到 DataSet 中的同一欄。這個範例示範如何處理 BindingComplete 事件,並確保當一個文字方塊的文字值變更時,另一個文字方塊和 DataGridView 控制項將會以正確的值進行更新。
此範例使用 BindingSource 來繫結資料來源和控制項。或者,您也可以將控制項直接繫結到資料來源並擷取 BindingManagerBase,以便從表單之 BindingContext 進行繫結,然後再處理 BindingManagerBase 的 BindingComplete 事件。如需執行這項操作的範例,請參閱關於 BindingManagerBase 之 BindingComplete 事件的說明頁。
' 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();
}
編譯程式碼
這個程式碼範例需要
System、System.Windows.Forms 和 System.Drawing 組件的參考。
已處理 Load 事件的表單,以及從表單的 Load 事件處理常式對範例中的 InitializeControlsAndDataSource 方法進行的呼叫。
請參閱
工作
HOW TO:使用 BindingSource 元件跨表單共用繫結資料