Задание значения в textbox из других классов, MVVM

307
19 октября 2017, 08:00

Есть классическое MVVM приложение VIEW содержит textbox, где Text="{Binding Message}" во ViewModel

private string _message { get; set; }
public string Message
{
    get { return _message; }
    set { _message = value; OnPropertyChanged("Message"); }
}

Как передавать это значение из других классов? Если у меня есть структура типа:

  • ModelALL -> ClassA -> ClassB -> ClassC
  • ModelALL -> ClassA -> ClassG
  • ModelALL -> ClassH

И сообщение надо передать из класса CalssC, ClassG, ClassH

Я делал через event типа

allModel.textAllModel += AllModel_TextChanged;
private void AllModel_TextChanged(object sender, TextMessage e)
{
    Message = e.message;
}

Но если у меня допустим 9 классов из которых надо передавать это сообщение, это надо каждый класс подписать на event и в нем объявить event.

В ClassA event на который будет подписан ModellAll, в ClassB event на который будет подписан CalssA, в ClassC event на который будет подписан CalssB и т.д.

И вот тут у меня вкрались подозрения что я делаю что то не так. Как нормальные люди обходят такие ситуации?

Answer 1

Напишите простой класс, который будет выступать посредником между отправителями и получателями сообщений, для начала можно его даже сделать статическим:

static class Logger
{
    public static event Action<string> MessageReceived;
    public static void SendMessage(string msg)
        => MessageReceived?.Invoke(msg);
}

Теперь все, кому нужно что-то сообщить, просто вызывают метод SendMessage():

Logger.SendMessage("Сообщение");

В конструкторе своей VM подпишитесь на событие MessageReceived:

Logger.MessageReceived += OnMessageReceived;

и обновите свойство:

void OnMessageReceived(string msg)
{
    if (!Application.Current.Dispatcher.CheckAccess())
        Application.Current.Dispatcher.InvokeAsync(() => Message = msg);
    else
        Message = msg;
}

Обратите внимание на использование Dispatcher - он позволяет обновлять свойства VM в потоке GUI (иначе будет возникать исключение - связанный вопрос).

Этот способ удобен еще и тем, что если вы захотите, например, параллельно писать все сообщения в файл - это не потребует глобальных изменений, достаточно будет просто подписать еще одно заинтересованное лицо на событие MessageReceived

READ ALSO
Является ли строка временем, проверка с помощью регулярного выражения

Является ли строка временем, проверка с помощью регулярного выражения

Имеется паттерн /d/d:/d/d:/d/d для времениМетоды Regex

287
Переадрессация и фильтры в ASP.NET MVC

Переадрессация и фильтры в ASP.NET MVC

Возникла проблема с выполнением блокировки пользователей на сайтеА именно, нет понимания как сделать автоматическое открытие страницы...

234
Дублирование в базе данных Entity Framework

Дублирование в базе данных Entity Framework

ПриветВозникла проблема

213