在.NET平台上,數據綁定是一項令人十分愉快的技術。利用數據綁定能減少代碼,簡化控制邏輯。
通常,可以將某個對象的一個屬性綁定到一個可視化的控件上,當屬性值改變時,控件上的顯示數據也隨之發生變化。要實現這一功能,只需要為自定義對象實現 INotifyPropertyChanged 接口即可。此接口中定義了 PropertyChanged 事件,我們只需在屬性值改變時觸發該事件即可。下面的例子說明如何綁定如何自定義可用於數據綁定的對象:
假設我們有自定義對象 CustomizedObject 和窗體上的 Label 控件 label1,想要將 CustomizedObject 的 Date 屬性和 label1.Text 關聯起來,Date 屬性值會在程序運行過程當中發生變化(例如點擊 Button 控件 button1),並且直接反映在 label1.Text 上。下面的代碼可以實現上述功能:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private CustomizedObject myObject;
public Form1()
{
InitializeComponent();
// 初始化CustomizedObject對象
myObject = new CustomizedObject { Date = DateTime.Now };
// 綁定對象的屬性到label1
label1.DataBindings.Add("Text", myObject, "Date");
}
private void button1_Click(object sender, EventArgs e)
{
// 點擊按鈕改變對象的屬性值
myObject.Date = myObject.Date.AddDays(1);
}
}
// 自定義對象 CustomizedObject 並實現 INotifyPropertyChanged 接口
public class CustomizedObject : INotifyPropertyChanged
{
private DateTime dateValue;
// 自定義一個 Date 屬性
public DateTime Date
{
get { return dateValue; }
set
{
dateValue = value;
NotifyPropertyChanged("Date");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// 添加一個觸發 PropertyChanged 事件的通用方法
protected virtual void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
其實從上面的例子中可以學習到如何自定義事件,這在開發控件時十分有用且非常重要。通過觀察 INotifyPropertyChanged 接口可以知道它內部有一個成員,那就是:
event PropertyChangedEventHandler PropertyChanged;
而其中的 PropertyChangedEventHandler 實質上是一個委托,明白了這一點就可以自定義事件了。
現在,開始為 Form1 自定義事件 DateChanged (事件一般是定義在控件或組件中的,這里只是為了說明其過程而沒有重新定義一個控件),首先需要一個事件參數類型:
public class DateChangedEventArgs : EventArgs
{
public DateTime OldValue { get; set; }
public DateTime NewValue { get; set; }
}
聲明一個事件處理委托
public delegate void DateChangedHandler(object sender, DateChangedEventArgs e);
我們可以將事件直接添加到Form1的定義中,但有時為了代碼的通用性,可以將事件封裝到一個接口中,例如:
public interface IDateChanged
{
event DateChangedHandler DateChanged;
}
然后我們為Form1實現 IDateChanged 接口,並在button1點擊時觸發該事件。以下是完整代碼:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form, IDateChanged
{
private CustomizedObject myObject;
public Form1()
{
InitializeComponent();
// 初始化CustomizedObject對象
myObject = new CustomizedObject { Date = DateTime.Now };
// 綁定對象的屬性到label1
label1.DataBindings.Add("Text", myObject, "Date");
// 添加 DateChanged 事件的處理邏輯
this.DateChanged += new DateChangedHandler(Form1_DateChanged);
}
private void Form1_DateChanged(object sender, DateChangedEventArgs e)
{
string message = string.Format(
"DateChanged event triggered!nOldValue: {0}nNew Value: {1}",
e.OldValue,
e.NewValue);
MessageBox.Show(message);
}
private void button1_Click(object sender, EventArgs e)
{
// 點擊按鈕改變對象的屬性值並觸發 DateChanged 事件
DateChangedEventArgs ev = new DateChangedEventArgs
{
OldValue = myObject.Date,
NewValue = myObject.Date.AddDays(1)
};
myObject.Date = ev.NewValue;
DateChangedMethod(ev);
}
#region IDateChanged Members
public event DateChangedHandler DateChanged;
// 添加一個觸發 DateChanged 事件的通用方法
protected virtual void DateChangedMethod(DateChangedEventArgs e)
{
if (DateChanged != null)
{
DateChanged(this, e);
}
}
#endregion
}
// 自定義對象 CustomizedObject 並實現 INotifyPropertyChanged 和 IDateChanged 接口
public class CustomizedObject : INotifyPropertyChanged
{
private DateTime dateValue;
// 自定義一個 Date 屬性
public DateTime Date
{
get { return dateValue; }
set
{
dateValue = value;
NotifyPropertyChanged("Date");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// 添加一個觸發 PropertyChanged 事件的通用方法
protected virtual void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
// DateChanged 事件委托
public delegate void DateChangedHandler(object sender, DateChangedEventArgs e);
// 用於封裝事件的接口
public interface IDateChanged
{
event DateChangedHandler DateChanged;
}
// DateChanged 事件參數
public class DateChangedEventArgs : EventArgs
{
public DateTime OldValue { get; set; }
public DateTime NewValue { get; set; }
}
}