Как определить, была ли модель изменена пользователем или кодом

#wpf #data-binding #inotifypropertychanged

#wpf #привязка к данным #inotifypropertychanged

Вопрос:

Моя модель реализует INotifyPropertyChanged , и у меня есть окно WPF, привязанное к нему (двухсторонние привязки).

Мне нужно знать, когда модель изменяется через связанный пользовательский интерфейс, чтобы я мог вызвать метод обновления из другого модуля (который затем копирует мою модель в свои внутренние структуры). Модель также может быть изменена другим модулем.

Как определить (в моем PropertyChanged обработчике событий), произошло ли изменение в моем пользовательском интерфейсе, а не в том другом модуле?

Я не хочу вызывать метод обновления, если это был другой модуль, который вызвал PropertyChanged событие.

Ответ №1:

Я сам довольно новичок в WPF, но единственным очевидным способом, который я могу придумать, чтобы сделать это, было бы добавить дополнительные методы set в модель, которые изменяют резервное хранилище без прямого изменения свойства и, таким образом, запуска события PropertyChanged. Чтобы устранить дублирование, установщик свойств, вероятно, также должен вызывать эти методы, и должен быть логический аргумент fireChangedEvent . Что-то вроде этого:

 public string SomeThing
{
    get { return _someThing; }
    set { SetSomeThing(value, true); }
}

public void SetSomeThing(string value, bool fireChangedEvent)
{
    _someThing = value;
    if(fireChangedEvent)
    {
        NotifyPropertyChanged("SomeThing");
    }
}
  

Тогда в другом модуле это было бы

 public void DoStuff
{
    // ...
    model.SetSomeThing("foo",false);
    // ...
}
  

Это не самый элегантный метод, который я знаю, и я надеюсь, что кто-нибудь другой сможет придумать что-нибудь поумнее, но я не могу придумать хорошего способа выяснить изнутри средства установки свойств, что именно устанавливает это свойство.

Надеюсь, это, по крайней мере, предложение по обходному пути.

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

1. Это тоже не так уж плохо 🙂 Можно также передать исходный код или некоторые другие данные в качестве аргумента вместо bool fireChangedEvent, который будет передан обработчику события для дальнейшей обработки.

Ответ №2:

Есть другой способ: с помощью привязки.SourceUpdated

Каждая привязка к окну должна быть установлена NotifyOnSourceUpdated=true , а общий обработчик для события SourceUpdated сделает все остальное (вызовет Window.ModelEdited событие, которое вызовет обновление в другом модуле).