INotifyPropertyChanged背后的概念是什么?

TCM*_*TCM 11 silverlight

使用MVVM的Silverlight的所有示例都使用名为IPropertyChanged的接口.它背后的概念是什么?为什么我们需要在设置某个值时引发事件?

例如:-

public class UserNPC:INotifyPropertyChanged
{
    private string name;
    public string Name { 
        get { return name; } 
        set { name = value; onPropertyChanged(this, "Name"); } 
    }
    public int grade;
    public int Grade { 
        get { return grade; } 
        set { grade = value; onPropertyChanged(this, "Grade"); } 
    }

    // Declare the PropertyChanged event
    public event PropertyChangedEventHandler PropertyChanged;

    // OnPropertyChanged will raise the PropertyChanged event passing the
    // source property that is being updated.
    private void onPropertyChanged(object sender, string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

INotifyPropertyChanged的确切目的是什么?

Ler*_*rve 15

您有以下依赖项:

查看→绑定→模型

现在,概念如下:

如果Model对象中的某些数据发生更改,则需要引发该PropertyChanged事件.为什么?因为Binding对象已经使用数据对象的PropertyChanged事件注册了一个方法.

因此,当您在Model对象中发生更改时,您需要做的就是引发事件并完成.

执行此操作时,Binding对象会通过您的事件获得有关更改的通知.该绑定反过来对象让视图对象知道发生了什么事情.然后,View对象可以在必要时更新UI.

代码示例

这里有一个可编辑的例子.设置几个断点,逐步执行代码,F11看看幕后发生了什么.请注意,此示例具有以下依赖项:视图→模型.我遗漏了Binding对象.

using System;
using System.ComponentModel;

namespace INotifyPropertyChangedDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create 2 listeners.
            View1 view1 = new View1();
            View2 view2 = new View2();

            // Create 1 data object.
            Model model = new Model();

            // Connect listener with data object.
            model.PropertyChanged += new PropertyChangedEventHandler(view1.MyPropertyChangedEventHandler);
            model.PropertyChanged += new PropertyChangedEventHandler(view2.MyPropertyChangedEventHandler);

            // Let data object publish change notification.
            model.FirstName = "new name";

            // Check whether all listeners got notified.
            // ... via console.
        }

        public class Model : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            private string firstName;
            public string FirstName
            {
                get { return firstName; }
                set
                {
                    if (firstName != value)
                    {
                        firstName = value;
                        if (PropertyChanged != null)
                        {
                            PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
                        }
                    }
                }
            }
        }

        public class View1
        {
            public void MyPropertyChangedEventHandler(object source, PropertyChangedEventArgs arg)
            {
                Console.WriteLine("Listener 1: Changed Property: {0}", arg.PropertyName);
                string newValue = ((Model) source).FirstName;
                Console.WriteLine("Listener 1: Changed Property Value: {0}", newValue);
            }
        }

        public class View2
        {
            public void MyPropertyChangedEventHandler(object source, PropertyChangedEventArgs arg)
            {
                Console.WriteLine("Listener 2: Changed Property: {0}", arg.PropertyName);
                string newValue = ((Model)source).FirstName;
                Console.WriteLine("Listener 2: Changed Property Value: {0}", newValue);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Jay*_*Jay 5

WPF和Silverlight中的MVVM是通过将UI元素绑定到视图模型来实现的.但是,当视图模型发生变化时,UI将如何知道更新自身?

INotifyPropertyChanged 简单地公开UI可以"监听"的事件,因此当控件"听到"它所绑定的属性发生了变化时,它可以"自我更新".

例如,假设您有一个TextBlock显示股票价格,并且它绑定到string Price视图模型的属性.反过来,视图模型使用服务每30秒更新一次股票价格.所以,每30秒一次,Price房产会发生变化:30秒前它是"29.20美元"现在是"29.12美元",从现在起30秒后它将是"28.10美元".在TextBlock当应用结合TextBlock每一次都被加载,但没有Price改变.但是,如果您INotifyPropertyChangedPricesetter中为属性"Price" 实现并引发事件,则TextBlock可以连接到事件,从而"知道"何时返回并"重新读取"​​该Price属性并更新显示的文本.