Возможно ли для View подписаться на событие ViewModel CLR? - PullRequest
2 голосов
/ 11 мая 2010

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

Что-нибудь в MVVM Light, позволяющее представлению прослушивать события и преобразовывать уведомления модели представления в действия пользовательского интерфейса с помощью декларативной разметки Xaml?

Ответы [ 4 ]

3 голосов
/ 17 мая 2010

Лично я нахожу технику извлечения событий из виртуальной машины и ловли их в представлении приемлемой в определенных обстоятельствах. Я обычно предпочитаю работать с Messenger для таких случаев, особенно, если вам нужны пользовательские аргументы событий (потому что достаточно много работы для объявления нового класса аргументов события и нового делегата).

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

Другой метод (например, для навигации, диалогов и т. Д.) - объявить интерфейс с необходимыми вам методами (например, IDialogService с методами AskConfirmation и ShowMessage). Затем попросите класс реализовать этот интерфейс (это может быть сам MainWindow / MainPage) и передать его в ViewModel (например, в конструкторе View сразу после вызова InitializeComponent). В ВМ вызывайте эти методы при необходимости. Преимущество этого метода в том, что его легко тестировать (просто смоделируйте IDialogService и проверьте, что методы вызываются).

Обычно я переключаюсь между Messenger и IDialogService в зависимости от различных факторов. Однако в последнее время я предпочитаю подход, основанный на интерфейсе, потому что его немного проще тестировать (но Messenger также достаточно тестируем, поэтому YMMV).

Ура, Laurent

2 голосов
/ 12 мая 2010

В «чистом» решении MVVM единственное, что должно связать View с ViewModel, - это Bindings. Ничто не мешает вам привести ваш DataContext к вашему типу ViewModel и перехватить событие в представлении, но это отчасти побеждает цель использования подхода MVVM. В качестве альтернативы попробуйте переосмыслить , почему вы думаете, что вам нужно поднять событие в представление:

  • Нужно отобразить всплывающее окно? Для создания всплывающих окон в представлении можно использовать различные связанные списки «всплывающих уведомлений» с соответствующим шаблоном, поскольку модель представления «вставляет» объекты уведомлений в связанную коллекцию.
  • Нужно принудительно открыть раскрывающийся список или выполнить какое-либо подобное действие пользовательского интерфейса? Свяжите соответствующее свойство в пользовательском интерфейсе со свойством модели представления, установите двусторонний режим и установите его соответствующим образом в модели представления.

и т. Д. И т. П.

1 голос
/ 14 мая 2010

В MVVMLight действительно поддерживается метод обработки сообщений из вашей ViewModel в View. Загляните внутрь пространства имен GalaSoft.MvvmLight.Messaging. Существует лучший способ отправки сообщений Dialod, чем в приведенном ниже примере, но это только быстрый пример.

Пример

ViewModel

public MainPageViewModel()
{
    Messenger.Default.Send("Payment");
}

View

public MainPage()
{
    Messenger.Default.Register<string>(this, DialogRequested);
}

private DialogRequested(string message)
{
    MessageBox.Show(message);
}
1 голос
/ 14 мая 2010

Вы правы, что иногда ViewModel необходимо взаимодействовать с View. Один из способов сделать это состоит в том, что ViewModel вызывает событие CLR, которое View слушает. Это можно сделать в программном обеспечении View.

MVVM - это не устранение выделенного кода для Views! Речь идет о разделении проблем и улучшении тестируемости с помощью модульных тестов.

Другой способ включить связь между ViewModel и View - это ввести интерфейс (IView). Дополнительную информацию об этом подходе можно найти на сайте проекта WPF Application Framework (WAF) .

...