zoukankan      html  css  js  c++  java
  • 通过 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(thisnew PropertyChangedEventArgs("Name"));   

                }   

            }   

        }   

      

        privatestring _address;   

        publicstring Address   

        {   

            get { return _address; }   

            set    

            {   

                _address = value;   

                if (PropertyChanged != null)   

                {   

                    PropertyChanged(thisnew 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(thisnew 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(400200);
            }

            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(thisnew 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(400200);
            }

            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(thisnew 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(thisnew 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 Code
    View Code
  • 相关阅读:
    拿webshell方法汇总
    Linux跑脚本用sh和./有什么区别?
    安全测试工具
    浏览器被劫持网上优秀的修复方法
    Linux 逻辑卷扩容
    sed替换文本
    mysql 用户创建,授权
    编程之约定
    java 对象成员变量初始化顺序
    java 静态成员初始化顺序
  • 原文地址:https://www.cnblogs.com/51net/p/3338739.html
Copyright © 2011-2022 走看看