Какова концепция INotifyPropertyChanged?

Во всех примерах Silverlight, использующих MVVM, используется интерфейс с именем 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));
        }
    }
}

Какова точная цель INotifyPropertyChanged?

11
задан TCM 24 August 2010 в 15:09
поделиться

3 ответа

У вас есть следующие зависимости:

Просмотр → Привязка → Модель

Теперь концепция следующая:

Если некоторые данные в вашем объекте Модель изменяются, вам необходимо поднять PropertyChanged событие. Почему? Поскольку объект Binding зарегистрировал метод с событием PropertyChanged объекта данных.

Итак, все, что вам нужно сделать, когда что-то изменится в вашем объекте Model , - это вызвать событие, и все готово.

Когда вы это делаете, объект Binding получает уведомление об изменении через ваше событие. Объект Binding , в свою очередь, позволяет объекту View узнать, что что-то произошло. Затем объект View может при необходимости обновить пользовательский интерфейс.

Пример кода

Вот вам компилируемый пример. Установите несколько точек останова, выполните код с помощью 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);
            }
        }
    }
}
15
ответ дан 3 December 2019 в 04:50
поделиться

MVVM в WPF & Silverlight реализуется путем привязки элементов пользовательского интерфейса к модели представления. Однако, когда модель представления изменяется, как пользовательский интерфейс узнает, что нужно обновить себя?

INotifyPropertyChanged просто предоставляет событие, которое пользовательский интерфейс может «слушать», поэтому, когда элемент управления «слышит» это свойство, которое он привязка изменилась, он может «обновляться».

Например, у вас есть TextBlock , который показывает цену акции, и он привязан к свойству string Price модели представления. Модель просмотра, в свою очередь, использует сервис для обновления цен на акции каждые 30 секунд. Таким образом, каждые 30 секунд свойство Price изменяется: 30 секунд назад оно было «29,20 доллара», теперь оно «29,12 доллара США», а через 30 секунд оно будет «28,10 доллара США».Привязка TextBlock применяется, когда загружается TextBlock , но не каждый раз, когда изменяется цена Price . Если, однако, вы реализуете INotifyPropertyChanged и вызовете событие для свойства Price в установщике Price , тогда TextBlock может подключиться к событию и, таким образом, " знать, «когда вернуться», «перечитать» свойство Price и обновить отображаемый текст.

5
ответ дан 3 December 2019 в 04:50
поделиться

Большинство элементов управления Silverlight отслеживают изменения отображаемых данных, просто подписываясь на события PropertyChanged.

например. элемент управления делает что-то подобное за кулисами:

    public void Loaded()
    {
        if (myDataObject is INotifyPropertyChanged)
        {
            (myDataObject as INotifyPropertyChanged).PropertyChanged +=new PropertyChangedEventHandler(onPropertyChanged);
        }
    }

Вот почему ObservableCollection используется вместо более простых списков в приложениях Silverlight. Они реализуют INotifyPropertyChanged, поэтому элементы управления, отображающие коллекции, могут видеть изменения, происходящие в списке, а также в отдельных элементах в списке.

3
ответ дан 3 December 2019 в 04:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: