Проблема здесь, похоже, архитектурная. MVVM - это многоуровневая архитектура, которая выглядит следующим образом:
Model -> View Model -> View
Модель - это самый низкий уровень, просмотр - самый высокий. Что еще более важно, каждый уровень не имеет прямой видимости ни на один из уровней над ним.
Проблема в вашем примере заключается в том, что вы нарушили разделение ответственности. У вас есть родительский класс, создающий PlaceholderTextBoxViewModel, что подразумевает его в модели представления. Однако этот же класс содержит свойство «Имя», которое на самом деле является данными, которые должны находиться на уровне вашей модели. Ваша существующая архитектура такова, что ваша модель представления не может видеть уровень данных, поэтому вам фактически пришлось настроить собственный механизм уведомления об изменении свойств, используя ссылку и делегат, чтобы ваша модель и модель представления были синхронизированы.
Выбросьте все и начните заново. Ваша модель должна содержать POCO, поэтому начните с чего-то вроде этого:
public class MyModel
{
public string Name {get; set;}
}
Затем, когда вы создаете свою модель представления, передайте экземпляр этого класса в его конструктор, чтобы он имел видимость:
public class MyViewModel : NotifiableViewModelBase
{
private MyModel Model;
public MyViewModel(MyModel model) => this.Model = model;
public string Text
{
get => this.Model.Name;
set
{
this.Model.Name = value;
RaisePropertyChanged(() => this.Text);
}
}
// ... etc ....
}
Я придерживался вашей номенклатуры использования «Name» в модели и «Text» в модели представления, на практике они обычно одинаковы, но решать вам. В любом случае, у вас все еще есть уведомление об изменении свойства в вашей модели представления, и это слой модели представления обновляет уровень модели.
Очевидно, есть много вариантов этого. Если вы не хотите, чтобы изменения сразу же распространялись на уровень вашей модели (а есть много случаев, когда вам это может не понадобиться), укажите текстовое поле поддержки (_Text) и выполняйте синхронизацию только в тех точках, которые вы хотите. происходят. И, конечно, если вы хотите go сделать еще один шаг, тогда классы вашей модели могут вместо этого реализовывать интерфейсы, и вы можете использовать внедрение зависимостей для внедрения этих интерфейсов в классы модели представления вместо предоставления им доступа к самим фактическим реализациям.
Прежде всего, имейте в виду, что единственная цель модели представления - подготовить данные уровня модели для использования представлением. Что-нибудь еще ... данные, домен, бизнес-логики c и c ... все это относится к уровню вашей модели, который вообще не должен иметь видимости на уровне модели представления.