Детские окна в МВВМ - PullRequest
3 голосов
/ 17 июня 2010

У меня проблемы с пониманием чего-то о MVVM. Мое приложение опирается на диалоги для определенных вещей. Вопрос в том, откуда эти детские окна? Согласно MVVM, модели представления должны содержать только businesslogic и иметь нулевые фактические знания об интерфейсе пользователя. Однако из какого другого места мне следует называть свои дочерние окна, учитывая, что они являются элементами пользовательского интерфейса?

Не создает ли это тесную связь между элементами?

Ответы [ 6 ]

1 голос
/ 17 июня 2010

Поскольку вы пометили вопрос с помощью Prism, я предложу способ, которым я делал это в прошлом, используя Prism.Вставьте IEventAggregator в вашу ViewModel, а затем, когда вы захотите открыть диалоговое окно, опубликуйте «ShowDialogEvent» или что-то в этом роде.Затем, есть другой модуль с именем «DialogModule» или любой другой, который после инициализации подписывается на это событие и показывает диалог.Кроме того, если вы хотите передать данные обратно в исходную ViewModel, пусть ViewModel диалогового окна опубликует «DialogCloseEvent» или что-то в этом роде с полезными данными, которые вам нужны.Затем вы можете подписаться на это событие в своей основной ViewModel.

0 голосов
/ 16 августа 2011

Я бы предложил использовать контроллер в этом сценарии, скажем, DI's dialogController, поддерживаемый диалоговой оболочкой.Модель представления источника (то есть, откуда исходит запрос на открытие диалогового окна) вызовет dialogController.ShowDialog(<<ViewNameToHostInRegion>>,<<RegionName>>).

Чтобы передать данные в диалоговое окно и в исходное представление и из него, вы можете использовать MessageBus.Таким образом, по существу, когда вы вызываете ShowDialog (), вы заполняете шину сообщений, и когда вызывается команда закрытия целевого представления (представление, размещенное в оболочке диалога) - скажем, с помощью кнопки «Выбрать» - пусть целевое представление добавляет / обновляет шину сообщений.Таким образом, модель исходного представления может работать с обновленными данными.

У нее много преимуществ:

1) Ваш исходный вид работает с диалоговым контроллером как BlackBox.то есть он не знает, что именно делает диалог.

2) Представление размещается в оболочке диалога - так что вы можете снова и снова использовать диалоговое окно

3) Модульное тестирование исходного представления ограничено, чтобы проверить фактическую функциональность текущегоviewmodel, а не тестировать диалоговое представление \ модель представления.

Один хедз-ап, с которым я столкнулся при этом, заключается в том, что при создании тестовых примеров вам может понадобиться написать тестируемый контроллер Dialog, который не показываетактуальный диалог при запуске тестов в связке.Поэтому вам нужно написать TestableDialogController, в котором ShowDialog ничего не делает (кроме наследования от IDialogController и обеспечения пустой реализации ShowDialog ().

Ниже приведен код psudeo:

LocalMessageBus.AddMessage(<MessageKey>,<MessageActualContentAsObject>);
dialogController.ShowDialog(<TargetViewName_SayEmployeeList>);
Employee selectedEmployee = LocalMessageBus.GetMessage(<MessageKey>) as Employee;
if (selectedEmployee != null)
{
//doSomework with selected employee
}
0 голосов
/ 18 июня 2010

Пример приложения ViewModel WPF Application Framework (WAF) демонстрирует, как отобразить Модальный диалог .

0 голосов
/ 18 июня 2010

Основной маршрут, который я использовал для этого, - создать команду внутри слоя View. Этот объект команды принимает параметр, который является объектом ViewModel, который вы хотите отобразить. Затем команда находит соответствующее ChildWindow, создает его и отображает его с параметром, заданным в качестве содержимого, или, тем не менее, вы его настроите. Таким образом, вы можете просто привязать свойство команды кнопки к этой команде, а ее параметр команды - к объекту, который вы хотите отобразить во всплывающем окне, и вашим объектам ViewModel никогда не нужно заботиться о том, как это отображается.

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

0 голосов
/ 17 июня 2010

Раньше я достигал этого, используя Unity для разрешения пользовательского интерфейса, который имеет метод Show() и завершенное событие.Затем в ViewModel я бы позвонил IScreen screen = container.Resolve<IScreen>(Resources.EditorWindowKey);, а затем просто позвонил screen.Show();.

Большим преимуществом этого является то, что я могу просто изменить конфигурацию Unity, чтобы удалить представление, когда я тестирую мойВМ.

0 голосов
/ 17 июня 2010
...