通过 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 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

由Dapper QueryMultiple 返回数据的问题

今天帮群友整理Dapper基础教程的时候手脚快了点,然后遇到了一个小问题,Dapper QueryMultiple 返回数据的问题 多个返回值用QueryMul...

280120
来自专栏向治洪

android-async-http框架源码分析

async-http使用地址 android-async-http仓库:git clone https://github.com/loopj/android...

23850
来自专栏挖坑填坑

Asp.net+Vue2构建简单记账WebApp之二(使用ABP迅速搭建.Net后台)

ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ASP.NET Boilerplate是一个用最佳实践...

19230
来自专栏xiaoheike

Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目

代码可以在github上看到:https://github.com/neo4j/neo4j/blob/2.3.3/community/embedded-exam...

13020
来自专栏算法修养

PAT 甲级 1019 General Palindromic Number(简单题)

1019. General Palindromic Number (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制...

356100
来自专栏ZKEASOFT

.Net Core在Middleware中解析RouteData

在ASP.Net Core中,如果直接在Middleware中获取RouteData返回的是空值,这是因为RouterMiddleware还没执行。但有些情况下...

20130
来自专栏技术小讲堂

ASP.NET AJAX(4)__客户端访问WebService服务器端释放WebService方法客户端访问WebService客户端访问PageMethod错误处理复杂数据类型使用基础客户端代理的

服务器端释放WebService方法 编写一个普通的WebService 为WebService类添加自定义的属性标记__ScriptServiceAttrib...

29170
来自专栏菩提树下的杨过

ExtJs学习笔记(22)-XTemplate + WCF 打造无刷新数据分页

ExtJs的Grid组件虽然不管从哪一方面来讲,都称得上是很好很强大,但是总会有一些应用场景并不需要这么多功能,比如网站的留言列表,开发者只想要一个简单的<li...

24850
来自专栏张善友的专栏

自定义Unity对象生命周期管理集成ADO.NET Entity Framework

在Unity中,从Unity 取得的实例为 Transient。如果你希望使用多线程方式,就需要在组成时使用lifecycle参数,这时候取出的组件就不再是同一...

36880
来自专栏菩提树下的杨过

ExtJs学习笔记(23)-ScriptTagProxy+XTemplate+WCF跨域取数据

ajax应用中跨域一直是一个非常麻烦的问题,目前也有一些解决办法,但要么比较麻烦,要么就不具备通用性,幸好ExtJs里的ScriptTagProxy提供了跨域读...

26780

扫码关注云+社区

领取腾讯云代金券