#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
событие, которое вызовет обновление в другом модуле).