INotifyPropertyChanged WPF

#c# #.net #wpf #mvvm

#wpf #inotifypropertychanged

Вопрос:

Какова цель INotifyPropertyChanged. Я знаю, что это событие запускается всякий раз, когда изменяется свойство, но как представление / пользовательский интерфейс может узнать, что это событие запущено:

Вот мой класс Customer, который реализует событие INotifyPropertyChanged:

 public class Customer : INotifyPropertyChanged
    {
        private string _firstName;

        public string LastName { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
                PropertyChanged(this,new PropertyChangedEventArgs(propertyName));

        }

        public string FirstName
        {
            get { return _firstName; }

            set
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
    }
 

Но теперь, как уведомить пользовательский интерфейс о том, что свойство изменилось. Например, когда пользователь присваивает null или empty первому имени, как я могу отобразить окно сообщений в пользовательском интерфейсе.

Ответ №1:

INotifyPropertyChanged позволяет элементам пользовательского интерфейса WPF (через стандартные механизмы привязки данных) подписываться на событие PropertyChanged и автоматически обновляться. Например, если у вас был текстовый блок, отображающий ваше свойство FirstName, с помощью INotifyPropertyChanged вы можете отобразить его в форме, и он будет автоматически обновляться при изменении свойства FirstName в коде.

Представление просто подписывается на событие, которое сообщает ему все необходимое. Событие включает имя измененного свойства, поэтому, если элемент пользовательского интерфейса привязан к этому свойству, он обновляется.

Ответ №2:

WPF может знать, потому что он может проверить, реализует ли объект этот интерфейс, затем привести объект к указанному интерфейсу и зарегистрироваться для события. Затем он может запустить инфраструктуру привязки для обновления отображения. Если вы хотите также реагировать, вы можете зарегистрироваться для того же события.

Комментарии:

1. Я знаю об обновлении пользовательского интерфейса из-за интерфейса INotifyPropertyChanged, но как я могу что-то изменить в пользовательском интерфейсе, основываясь на том факте, что FirstName равно нулю или пусто.

2. Если вы действительно не хотите привязываться к событию и делать то, что вы хотите сделать в императивном порядке, вы можете сделать это декларативно, используя комбинацию, например, преобразователя для string -> bool, инкапсулирующего вашу логику, а затем управлять некоторым свойством видимости с помощью результирующего bool. Однако я не вижу, как открыть окно сообщения из XAML.

Ответ №3:

РЕДАКТИРОВАТЬ: я перечитал ваш вопрос и некоторые ваши комментарии. Вот возможное решение, использующее событие DataContextChanged и интерфейс INotifyPropertyChanged для вашего объекта Customer. Вам также следует изучить проверку привязки данных в WPF и .Net 3.5.

 <TextBox Text="{Binding FirstName}" />

// assuming:
// myWindow.DataContext = new Customer();
myWindow.DataContextChanged  = MyWindow_DataContextChanged;

private void MyWindow_DataContextChanged(object sender,
    DependencyPropertyChangedEventArgs e)
{
    var oldCustomer = e.OldValue as Customer;
    if (oldCustomer != null)
    {
        oldCustomer.PropertyChanged -= Customer_CheckProps;
    }

    var newCustomer = e.NewValue as Customer;
    if (newCustomer != null)
    {
        newCustomer.PropertyChanged  = Customer_CheckProps;
    }
}

private void Customer_CheckProps(object sender, PropertyChangedEventArgs e)
{
    var customer = sender as Customer;
    if (customer != null)
    {
        if (e.PropertyName == "FirstName"
            amp;amp; String.IsNullOrEmpty(customer.FirstName))
        {
            // Display Message Box
        }
    }
}