Как я могу подписаться на событие PropertyChanged в моей модели ViewModel?

У меня есть основная функциональность, заключенная в ViewModelBase

Теперь я хочу увидеть, когда событие PropertyChanged было вызвано ViewModelBase и действовать на него. Например, когда одно свойство было изменено на ViewModelBase - я хочу изменить свойство на моем ViewModel

Как мне это достичь?

public class MaintainGroupViewModel : BaseViewModel<MEMGroup>
    {


public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
        where T : Entity
    {

Ответ 1

Я обеспокоен тем, что вы эффективно выполняете "ручную привязку" (bad) для свойства в производном классе к значению базового класса (также плохо). Весь смысл использования наследования заключается в том, что производный класс может получить доступ к вещам в базовом классе. Используйте модификатор protected, чтобы указать, что вещи должны быть доступны только для производных классов.

Я бы предложил этот (потенциально) более правильный метод:

Базовый класс:

protected virtual void OnMyValueChanged() { }

Производный класс:

protected override void OnMyValueChanged() { /* respond here */ }

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

В терминах "когда одно свойство было изменено на ViewModelBase - я хочу изменить свойство на моем ViewModel",... они являются одним и тем же объектом!

Ответ 2

Обычно я использую регистр для события PropertyChanged в классе Constructor

public MyViewModel()
{
    this.PropertyChanged += MyViewModel_PropertyChanged;
}

и обработчик события PropertyChanged выглядит следующим образом:

void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch (e.PropertyName)
    {
        case "SomeProperty":
            // Do something
            break;
    }
}

Ответ 3

Прямой способ подписаться на изменения свойств использует INotifyPropertyChanged, если ваш BaseViewModel реализует его:

PropertyChanged += (obj, args) =>
   { System.Console.WriteLine("Property " + args.PropertyName + " changed"); }

Если это не так, то это должно быть DependencyObject, и ваши свойства должны быть DependencyProperties (что, вероятно, является более сложным способом).

В этой статье описывается, как подписаться на изменения DependencyProperty.