前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过 INotifyPropertyChanged 实现观察者模式

通过 INotifyPropertyChanged 实现观察者模式

作者头像
跟着阿笨一起玩NET
发布2018-09-18 17:55:52
2.8K0
发布2018-09-18 17:55:52
举报
文章被收录于专栏:跟着阿笨一起玩NET

INotifyPropertyChanged

它的作用:向客户端发出某一属性值已更改的通知。

当属性改变时,它可以通知客户端,并进行界面数据更新.而我们不用写很多复杂的代码来更新界面数据,这样可以做到方法简洁而清晰,松耦合和让方法变得更通用.可用的地方太多了:例如上传进度,实时后台数据变更等地方。

它的作用:向客户端发出某一属性值已更改的通知。

当属性改变时,它可以通知客户端,并进行界面数据更新.而我们不用写很多复杂的代码来更新界面数据,这样可以做到方法简洁而清晰,松耦合和让方法变得更通用.可用的地方太多了:例如上传进度,实时后台数据变更等地方.目前我发现winform和silverlight都支持,确实是一个强大的接口.

代码语言:javascript
复制
在构造函数中先绑定
 


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

代码语言:javascript
复制
// 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

代码语言:javascript
复制
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();界面数据才会即使更新。

代码语言:javascript
复制
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

  很好,很强大,高端大气上档次 

代码语言:javascript
复制
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
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-09-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档