HOW TO:使用 BindingSource 和 INotifyPropertyChanged 介面引發變更告知
當資料來源中的型別實作 INotifyPropertyChanged 介面時,以及當屬性值變更而使該型別引發 PropertyChanged 事件時,BindingSource 元件會自動偵測資料來源中的變更。 這項功能將會相當實用,因為繫結至 BindingSource 的控制項會因而在資料來源值發生變更時自動更新。
注意事項 |
---|
如果資料來源實作 INotifyPropertyChanged,而且您正在執行非同步作業,請不要在背景執行緒上對資料來源進行變更, 而是應該在背景執行緒上讀取資料,然後在 UI 執行緒上將資料合併至清單中。 |
範例
下列程式碼範例將示範 INotifyPropertyChanged 介面的簡單實作。 同時也會顯示 BindingSource 如何在 BindingSource 繫結至 INotifyPropertyChanged 型別清單時,自動將資料來源變更傳遞給繫結控制項。
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Common
Imports System.Diagnostics
Imports System.Drawing
Imports System.Data.SqlClient
Imports System.Windows.Forms
' This form demonstrates using a BindingSource to bind
' a list to a DataGridView control. The list does not
' raise change notifications, however the DemoCustomer type
' in the list does.
Public Class Form1
Inherits System.Windows.Forms.Form
' This button causes the value of a list element to be changed.
Private changeItemBtn As New Button()
' This DataGridView control displays the contents of the list.
Private customersDataGridView As New DataGridView()
' This BindingSource binds the list to the DataGridView control.
Private customersBindingSource As New BindingSource()
Public Sub New()
' Set up the "Change Item" button.
Me.changeItemBtn.Text = "Change Item"
Me.changeItemBtn.Dock = DockStyle.Bottom
AddHandler Me.changeItemBtn.Click, AddressOf changeItemBtn_Click
Me.Controls.Add(Me.changeItemBtn)
' Set up the DataGridView.
customersDataGridView.Dock = DockStyle.Top
Me.Controls.Add(customersDataGridView)
Me.Size = New Size(800, 200)
AddHandler Me.Load, AddressOf Form1_Load
End Sub 'New
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Me.Load
' Create and populate the list of DemoCustomer objects
' which will supply data to the DataGridView.
Dim customerList As New BindingList(Of DemoCustomer)
customerList.Add(DemoCustomer.CreateNewCustomer())
customerList.Add(DemoCustomer.CreateNewCustomer())
customerList.Add(DemoCustomer.CreateNewCustomer())
' Bind the list to the BindingSource.
Me.customersBindingSource.DataSource = customerList
' Attach the BindingSource to the DataGridView.
Me.customersDataGridView.DataSource = Me.customersBindingSource
End Sub 'Form1_Load
' This event handler changes the value of the CompanyName
' property for the first item in the list.
Private Sub changeItemBtn_Click(ByVal sender As Object, ByVal e As EventArgs)
' Get a reference to the list from the BindingSource.
Dim customerList As BindingList(Of DemoCustomer) = _
CType(customersBindingSource.DataSource, BindingList(Of DemoCustomer))
' Change the value of the CompanyName property for the
' first item in the list.
customerList(0).CustomerName = "Tailspin Toys"
End Sub
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
End Class
' This class implements a simple customer type
' that implements the IPropertyChange interface.
Public Class DemoCustomer
Implements INotifyPropertyChanged
' These fields hold the values for the public properties.
Private idValue As Guid = Guid.NewGuid()
Private customerNameValue As String = String.Empty
Private phoneNumberValue As String = String.Empty
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
' The constructor is private to enforce the factory pattern.
Private Sub New()
customerNameValue = "Customer"
phoneNumberValue = "(555)555-5555"
End Sub
' This is the public factory method.
Public Shared Function CreateNewCustomer() As DemoCustomer
Return New DemoCustomer()
End Function
' This property represents an ID, suitable
' for use as a primary key in a database.
Public ReadOnly Property ID() As Guid
Get
Return Me.idValue
End Get
End Property
Public Property CustomerName() As String
Get
Return Me.customerNameValue
End Get
Set(ByVal value As String)
If Not (value = customerNameValue) Then
Me.customerNameValue = value
NotifyPropertyChanged("CustomerName")
End If
End Set
End Property
Public Property PhoneNumber() As String
Get
Return Me.phoneNumberValue
End Get
Set(ByVal value As String)
If Not (value = phoneNumberValue) Then
Me.phoneNumberValue = value
NotifyPropertyChanged("PhoneNumber")
End If
End Set
End Property
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Drawing;
using System.Data.SqlClient;
using System.Windows.Forms;
// This form demonstrates using a BindingSource to bind
// a list to a DataGridView control. The list does not
// raise change notifications, however the DemoCustomer type
// in the list does.
public class Form1 : System.Windows.Forms.Form
{
// This button causes the value of a list element to be changed.
private Button changeItemBtn = new Button();
// This DataGridView control displays the contents of the list.
private DataGridView customersDataGridView = new DataGridView();
// This BindingSource binds the list to the DataGridView control.
private BindingSource customersBindingSource = new BindingSource();
public Form1()
{
// Set up the "Change Item" button.
this.changeItemBtn.Text = "Change Item";
this.changeItemBtn.Dock = DockStyle.Bottom;
this.changeItemBtn.Click +=
new EventHandler(changeItemBtn_Click);
this.Controls.Add(this.changeItemBtn);
// Set up the DataGridView.
customersDataGridView.Dock = DockStyle.Top;
this.Controls.Add(customersDataGridView);
this.Size = new Size(800, 200);
this.Load += new EventHandler(Form1_Load);
}
private void Form1_Load(System.Object sender, System.EventArgs e)
{
// Create and populate the list of DemoCustomer objects
// which will supply data to the DataGridView.
BindingList<DemoCustomer> customerList = new BindingList<DemoCustomer>();
customerList.Add(DemoCustomer.CreateNewCustomer());
customerList.Add(DemoCustomer.CreateNewCustomer());
customerList.Add(DemoCustomer.CreateNewCustomer());
// Bind the list to the BindingSource.
this.customersBindingSource.DataSource = customerList;
// Attach the BindingSource to the DataGridView.
this.customersDataGridView.DataSource =
this.customersBindingSource;
}
// Change the value of the CompanyName property for the first
// item in the list when the "Change Item" button is clicked.
void changeItemBtn_Click(object sender, EventArgs e)
{
// Get a reference to the list from the BindingSource.
BindingList<DemoCustomer> customerList =
this.customersBindingSource.DataSource as BindingList<DemoCustomer>;
// Change the value of the CompanyName property for the
// first item in the list.
customerList[0].CustomerName = "Tailspin Toys";
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
// This is a simple customer class that
// implements the IPropertyChange interface.
public class DemoCustomer : INotifyPropertyChanged
{
// These fields hold the values for the public properties.
private Guid idValue = Guid.NewGuid();
private string customerNameValue = String.Empty;
private string phoneNumberValue = String.Empty;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
// The constructor is private to enforce the factory pattern.
private DemoCustomer()
{
customerNameValue = "Customer";
phoneNumberValue = "(555)555-5555";
}
// This is the public factory method.
public static DemoCustomer CreateNewCustomer()
{
return new DemoCustomer();
}
// This property represents an ID, suitable
// for use as a primary key in a database.
public Guid ID
{
get
{
return this.idValue;
}
}
public string CustomerName
{
get
{
return this.customerNameValue;
}
set
{
if (value != this.customerNameValue)
{
this.customerNameValue = value;
NotifyPropertyChanged("CustomerName");
}
}
}
public string PhoneNumber
{
get
{
return this.phoneNumberValue;
}
set
{
if (value != this.phoneNumberValue)
{
this.phoneNumberValue = value;
NotifyPropertyChanged("PhoneNumber");
}
}
}
}
編譯程式碼
這個範例需要:
- System、System.Data、System.Drawing 和 System.Windows.Forms 組件的參考。
如需從 Visual Basic 或 Visual C# 的命令列建置這個範例的詳細資訊,請參閱從命令列建置 (Visual Basic) 或使用 csc.exe 建置命令列。 您也可以透過將程式碼貼入新的專案,在 Visual Studio 中建置此範例。 如需詳細資訊,請參閱HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例 和 HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例 和 HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例 和 HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例 和 如何:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例.
請參閱
工作
HOW TO:使用 BindingSource ResetItem 方法引發變更通知