专栏首页跟着阿笨一起玩NET通过 INotifyPropertyChanged 实现观察者模式

通过 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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • PropertyGrid绑定Dictionary

    本文摘抄:http://greatverve.cnblogs.com/archive/2012/02/08/propergrid-Dictionary.ht...

    跟着阿笨一起玩NET
  • linq Distinct 去除重复数据

    转载:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html

    跟着阿笨一起玩NET
  • C# 在 webBrowser 光标处插入 html代码 .

    跟着阿笨一起玩NET
  • 砍人、切水果两不误!《Virtual Ninja VR》现已登陆Steam

    VRPinea
  • 安卓滚动字幕以及TextSwitcher、ImageSwitcher使用

    项目源码下载:https://github.com/libin7278/TextSwitcher

    先知先觉
  • 数据源管理 | 主从库动态路由,AOP模式读写分离

    在相对复杂的应用服务中,配置多个数据源是常见现象,例如常见的:配置主从数据库用来写数据,再配置一个从库读数据,这种读写分离模式可以缓解数据库压力,提高系统的并发...

    知了一笑
  • 当然是原谅她啊!然后利用这个H5给别人丢绿帽子!

    哈哈哈哈哈,话说,我快要笑死了。 什么鬼??? 因为花叔发现一个草鸡搞笑的H5,今天花叔不说产品,不说运营,也不说技术,只转发一个H5游戏。 首先我问问,有人看...

    花叔
  • rbind的坑?

    这两天在合并数据的时候发现了一个神奇的现象,rbind竟然可以合并不同列名的矩阵,而且不做任何提醒,在三个版本的R上都遇到了这个现象,看来不是个例。这样会明显造...

    用户1075469
  • RFC1945 超文本传输协议--HTTP/1.0 之二

    苦叶子
  • [WCF安全系列]谈谈WCF的客户端认证[Windows认证]

    结束了服务认证的介绍之后,我们接着介绍WCF双向认证的另一个方面,即服务对客户端的认证,简称客户端认证。客户端认证采用的方式决定于客户端凭证的类型,内容只要涉及...

    蒋金楠

扫码关注云+社区

领取腾讯云代金券