最近做項目用到DataGridView,用它綁定數據源后,如果數據源中的數據修改無法及時刷新到控件上,必須切換單元格的焦點才能導致刷新顯示新數值,通過查官方文檔,用INotifyPropertyChanged解決此問題。
案例如下:
首先定義一個類:Customer
public class Customer { public string CustomerName { get; set; } public string PhoneNumber { get; set; } }
創建一個綁定數據集:
private BindingList<Customer> customers = new BindingList<Customer>();
向數據集中添加數據並綁定到控件:
customers.Add(new Customer() { CustomerName = "張三", PhoneNumber = "010-5263" }); customers.Add(new Customer() { CustomerName = "李四", PhoneNumber = "010-8823" }); dataGridView1.DataSource = customers;
修改數據源:
customers[0].CustomerName = "王五";
此時,dataGridView1中沒有及時刷新顯示新數據。因為數據修改時並沒有通知到控件,為此讓Customer實現INotifyPropertyChanged接口,該接口只包含一個事件,當屬性值改變時,觸發該事件,從而導致注冊該事件的方法被執行,達到通知控件的目的。這是通過事件實現觀察者模式。
Customer實現INotifyPropertyChanged接口:
public class Customer:INotifyPropertyChanged { private string _customerName; private string _phoneNumber; public string CustomerName { get { return _customerName; } set { if(_customerName!=value) { _customerName = value; PropertyChanged(this, new PropertyChangedEventArgs("CustomerName")); } } } public string PhoneNumber { get { return _phoneNumber; } set { if (_phoneNumber != value) { _phoneNumber = value; PropertyChanged(this, new PropertyChangedEventArgs("PhoneNumber")); } } } public event PropertyChangedEventHandler PropertyChanged = delegate { }; }
此時,再次執行修改數據源的代碼,控件會及時刷新數據顯示,因為屬性值改變時通知了控件進行相應的處理。
如果在數據源中添加或刪除一條數據,控件也會及時刷新顯示,怎么回事?原來BindingList<T>實現了IBindingList接口,該接口聲明了事件 ListChangedEventHandler,BindingList<T>在添加或刪除記錄時,觸發該事件。顯然,控件在綁定數據集(customers)時,訂閱了該事件。
