通過 INotifyPropertyChanged 實現觀察者模式

INotifyPropertyChanged

它的作用:向客戶端發出某一屬性值已更改的通知。

當屬性改變時,它可以通知客戶端,並進行界面數據更新.而我們不用寫很多複雜的代碼來更新界面數據,這樣可以做到方法簡潔而清晰,鬆耦合和讓方法變得更通用.可用的地方太多了:例如上傳進度,實時後臺數據變更等地方。

它的作用:向客戶端發出某一屬性值已更改的通知。

當屬性改變時,它可以通知客戶端,並進行界面數據更新.而我們不用寫很多複雜的代碼來更新界面數據,這樣可以做到方法簡潔而清晰,鬆耦合和讓方法變得更通用.可用的地方太多了:例如上傳進度,實時後臺數據變更等地方.目前我發現winform和silverlight都支持,確實是一個強大的接口.

在構造函數中先綁定
 


public Class_Name()   
{   
    User user = new User();   
    user.Name = "your name";   
    user.Address = "your address";   
  
    textBox1.Text = user.Name;   
    textBox2.Text = user.Address;   
}   

編寫一個簡單的業務類 
 

按 Ctrl+C 複製代碼
publicclass User : INotifyPropertyChanged   
{   
    publicevent PropertyChangedEventHandler PropertyChanged;   
  
    privatestring _name;   
    publicstring Name   
    {   
        get { return _name; }   
        set    
        {   
            _name = value;   
           if(PropertyChanged != null)   
            {   
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));   
            }   
        }   
    }   
  
    privatestring _address;   
    publicstring Address   
    {   
        get { return _address; }   
        set    
        {   
            _address = value;   
            if (PropertyChanged != null)   
            {   
                PropertyChanged(this, new PropertyChangedEventArgs("Address"));   
            }   
        }   
    }   
}
按 Ctrl+C 複製代碼
 
 ObservableCollection
 
綁定到集合
 
數據綁定的數據源對象可以是一個含有數據的單一對象,也可以是一個對象的集合。之前,一直在討論如何將目標對象與一個單一對象綁定。Silverlight中的數據綁定還能將目標對象與集合對象相綁定,這也是很常用的。比如顯示文章的題目列表、顯示一系列圖片等。
 
如果要綁定到一個集合類型的數據源對象,綁定目標可以使用ItemsControl,如ListBox或DataGrid等。另外,通過定製ItemsControl的數據模板(DataTemplate),還可以控制集合對象中每一項的顯示。
 
使用ObservableCollection
 
數據源集合對象必須繼承IEnumerable接口,爲了讓目標屬性與數據源集合的更新(不但包括元素的修改,還包括元素的增加和刪除)保持同步,數據源集合還必須實現INotifyPropertyChanged接口和INotifyCollectionChanged接口。
 
在Silverlight中創建數據源集合可以使用內建的ObservableCollection類,因爲ObservableCollection類既實現了INotifyPropertyChanged接口,又實現了INotifyCollectionChanged接口。使用ObservableCollection類不但可以實現Add、Remove、Clear和Insert操作,還可以觸發PropertyChanged事件。View Code

本文轉載http://www.cnblogs.com/ynbt/archive/2013/01/02/2842385.html

// 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");
            }
        }
    }
}View Code

(2)、msdn經典例;當數據發生變化時候,DataGridView自動變化。繼承INotifyPropertyChanged接http://msdn.microsoft.com/zh-cn/library/system.componentmodel.inotifypropertychanged.aspx

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
// Change the namespace to the project name.
namespace TestNotifyPropertyChangedCS
{
    // 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 partial class Form1 : 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()
        {
            InitializeComponent();
            // 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(400, 200);
        }
        private void Form1_Load(object sender, 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";
            customerList[0].PhoneNumber = "(708)555-0150";
        }
    }
    // 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;
        // This method is called by the Set accessor of each property.
        // The CallerMemberName attribute that is applied to the optional propertyName
        // parameter causes the property name of the caller to be substituted as an argument.
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        // The constructor is private to enforce the factory pattern.
        private DemoCustomer()
        {
            customerNameValue = "Customer";
            phoneNumberValue = "(312)555-0100";
        }
        // 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();
                }
            }
        }
        public string PhoneNumber
        {
            get
            {
                return this.phoneNumberValue;
            }
            set
            {
                if (value != this.phoneNumberValue)
                {
                    this.phoneNumberValue = value;
                    NotifyPropertyChanged();
                }
            }
        }
    }
}View Code

BindingList<DemoCustomer> 如果換成List<DemoCustomer>,DataGridView必需調用DataGridView.Refresh();界面數據纔會即使更新。

public partial class Form1 : 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()
        {
            InitializeComponent();
            // 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(400, 200);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            // Create and populate the list of DemoCustomer objects
            // which will supply data to the DataGridView.
            //BindingList<DemoCustomer> customerList = new BindingList<DemoCustomer>();
            List<DemoCustomer> customerList = new List<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.DataSource;
        }
        // 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>;
            List<DemoCustomer> customerList =
                this.customersBindingSource.DataSource as List<DemoCustomer>;
            // Change the value of the CompanyName property for the 
            // first item in the list.
            customerList[0].CustomerName = "Tailspin Toys";
            customerList[0].PhoneNumber = "(708)555-0150";
            //如果數據源是換成List<T>只有刷新以後才能即使更新。
            this.customersDataGridView.Refresh();
        }

    

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

    

    }
    // 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");
                }
            }
        }
    }View Code

(3)、讓INotifyPropertyChanged的實現更優雅一些http://tech.ddvip.com/2009-05/1242645380119734_2.html

  很好,很強大,高端大氣上檔次 

public class DemoCustomer1 : PropertyChangedBase
    {
        // These fields hold the values for the public properties.
        private Guid idValue = Guid.NewGuid();
        private string customerNameValue = String.Empty;
        private string phoneNumberValue = String.Empty;

        // The constructor is private to enforce the factory pattern.
        private DemoCustomer1()
        {
            customerNameValue = "Customer";
            phoneNumberValue = "(555)555-5555";
        }
        // This is the public factory method.
        public static DemoCustomer1 CreateNewCustomer()
        {
            return new DemoCustomer1();
        }
        // 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;
                    this.NotifyPropertyChanged(p => p.CustomerName);
                    //NotifyPropertyChanged("CustomerName");
                }
            }
        }
        public string PhoneNumber
        {
            get
            {
                return this.phoneNumberValue;
            }
            set
            {
                if (value != this.phoneNumberValue)
                {
                    this.phoneNumberValue = value;
                    this.NotifyPropertyChanged(p => p.PhoneNumber);
                    //NotifyPropertyChanged("PhoneNumber");
                }
            }
        }
    }

    /// <summary>
    /// 基類
    /// </summary>
    public class PropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    /// <summary>
    /// 擴展方法
    /// </summary>
    public static class PropertyChangedBaseEx
    {
        public static void NotifyPropertyChanged<T, TProperty>(this T propertyChangedBase, Expression<Func<T, TProperty>> expression) where T : PropertyChangedBase
        {
            var memberExpression = expression.Body as MemberExpression;
            if (memberExpression != null)
            {
                string propertyName = memberExpression.Member.Name;
                propertyChangedBase.NotifyPropertyChanged(propertyName);
            }
            else
                throw new NotImplementedException();
        }
    }View CodeView Code
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章