В MVVM должны ли ViewModel или View отвечать за создание новых представлений?

11

В моем приложении WPF я хочу создать новый вид. Где я должен это сделать - во ViewModel или Model ?

Приложение представляет собой (очень простой на данный момент) инструмент в форме окна с одной кнопкой «Отправить». В случае, если выбран один из флажков, должно появиться новое окно с использованием той же модели представления, чтобы запросить у пользователя дополнительные сведения. Для целей этого вопроса давайте рассмотрим только новый подход окна, не рассматривая другие подходы, такие как показанная / скрытая панель.

В идеале в View не должно быть никакого кода. Кроме того, поскольку View не имеет никакой логики, VM изначально должна проверить, нужно ли создавать новое представление, и - когда это необходимо - вернуть эту ответственность обратно на View, что приведет к раздуванию кода.

С другой стороны, создание нового представления в ViewModel нарушает принцип, согласно которому ViewModel не должен ничего знать о View.

Итак, лучше ли создавать новые представления в View или ViewModel?

Mac70
источник
1
Я не очень понимаю ваш вопрос. Что означает «In View или ViewModel»? Модели представления не создают представления, и представления, конечно, не создают себя.
Роберт Харви,
1
Я имею в виду, какой из этих слоев должен отвечать за создание новых представлений - сигнал для этого должен поступать откуда-то, когда происходит действие. Я полностью исключил модель из этого вопроса, потому что она вообще не должна ничего знать о внешнем интерфейсе.
Mac70
Может быть, я не правильно понимаю ваш вопрос, оба они не должны мешать вашему мнению. Если вы хотите создать новое представление в вашей viewModel, есть ли причина, по которой вы не используете фреймы в xaml для изменения содержимого Window с привязкой к вашей текущей viewModel?
Сиобхан

Ответы:

8

Я использую внедрение зависимостей и внедрение IViewFactoryв модель представления для соблюдения обоих ограничений.

А ProductViewModel(например) звонки this.viewFactory.Show("Details", this)открывать ProductDetailsViewс собой как ProductViewModel. Также можно открыть представление на основе другой модели представления с помощью this.viewFactory.Show<ClientViewModel>().

Реализация (на самом деле их несколько для WinForms, простая Wpf Windows, оболочка Wpf с вкладками, ...) основана на StructureMapсоглашении. Представления обозначают свою модель представления через IView<ProductViewModel>интерфейс.

Таким образом, модель представления ничего не знает о представлении, кроме его роли (представление по умолчанию, представление сведений, ...), и представление не содержит кода для создания другого представления. Кроме того, модели представлений находятся в отдельной сборке, которая не ссылается ни на одну сборку Wpf.

Philippe
источник
7

Теоретический ответ

Если у вас есть ViewModelдействия, действия, которые имеют косметические эффекты (например, выделение элемента при наведении курсора мыши), являются заданиями View, в то время как действия, которые имеют "реальные" эффекты (например, порождают новое окно), являются заданием ViewModel.

Таким образом, создание нового окна - это работа для ViewModel. Однако ни View, ни the не ViewModelдолжны знать, как именно создать Window, это не входит в их обязанности и относится к другому классу.

Можно утверждать, что создание нового окна - это работа для View. Хотя я бы не согласился, в такой дискуссии нет особой ценности, потому что на практике это не конец света, если вы поместите этот код в View, и также не так много работы, чтобы переместить его ViewModelв более поздний момент. , Важной частью является то, что логика для создания нового окна содержится в независимом классе, обычно это своего рода WindowFactory. Смысл MVVM, MVP, MVC и т. Д. В том, что у вас есть классы с небольшим количеством четко определенных обязанностей. Вот почему вы не добавляете дополнительные обязанности к View, ViewModelили Modelесли вам не нужно.

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

Практический ответ

Речь идет о «инструменте в форме окна с одной кнопкой« Отправить » . Итак, вот бесстыдная заглушка для моего соответствующего ответа: зачем использовать MVVM?

Подводя итог, что говорит этот ответ: Сделайте это простым. Да, и имейте в виду приведенный выше теоретический ответ для реализации, когда окно с одной кнопкой станет более сложным.

Питер
источник