2009-04-02 3 views
9

У меня возник вопрос о обязанностях VM, когда речь заходит о всплывающих окнах. Когда приложение выскакивают окно сообщения или какой-то диалог (с MVVM), два варианта, которые мы имеем, являются:Правильный способ отображения всплывающих окон с использованием шаблона WPF M-V-VM

  1. ввод UI (ShowDialog()) код в виртуальной машине, которая, кажется, плохо
  2. есть VM отправляет какое-то событие, которое пользовательский интерфейс может подписаться и отобразить диалог в коде позади (но мы стремимся к нулевому коду за :) :)

Как вы, ребята, решаете этот случай?

+0

Интересно, поможет ли эта нить. [Http://stackoverflow.com/questions/454868/handling-dialogs-in-wpf-with-mvvm](http://stackoverflow.com/questions/454868/handling-dialogs-in-wpf-with-mvvm) – djcouchycouch

ответ

2

Не помещайте код UI в виртуальную машину, это просто вызывает много головных болей по дороге.

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

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

0

Я использую события, обрабатываемые представлением. Мне это не нравится на 100%, но это позволяет автоматизировать тестирование.

0

Создайте интерфейс для своего всплывающего диалогового окна, даже если вы планируете использовать почтовый ящик.

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

Получите ваше мнение от зарегистрированного всплывающего окна.

1

несколько других вариантов, не указанных другими:

ретрансляционной Команда

ВМ выполняет команду, которая мне нравится называть «команду реле». Это команда, которой управляет кто-то другой, и VM не заботится о том, кто. Выполнение команды ничего не делает, но вызывает событие Executed. Ваше мнение будет подписано на это событие и отобразит содержимое в новом Window (содержимое будет передано в качестве параметра команды).

Обратите внимание, что команда реле не является маршрутизируемой командой. Он не ищет обработчик в своей логике выполнения. Это просто событие.

Услуга,

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

1

Я бы сказал, что лучший способ - определить Popup в XAML, а затем использовать DataTrigger, связанный с каким-либо условием в вашем ViewModel, чтобы скрыть или отобразить его.Затем, если вам нужно обработать возвращаемое значение из Popup, введите EventTrigger в Popup, чтобы управлять объектами ViewModel, чтобы отразить это изменение.

Существует много разговоров вокруг такого рода областей, которые, я думаю, связаны с тем, что люди привыкли программировать в мире WinForms. Я еще не нашел решение, где мне нужен какой-либо код в представлении, кроме как для извлечения исходных данных или для установки DataContexts

0

Я согласен с Карлосом в том, что использование подписки на мероприятие в представлении не является хорошим выбором. Насколько я понимаю MVVM, это приводит к тому, чтобы исключить любой код из представления, и мне это очень нравится :). Одним из провалов MVVM является способность его тестировать. Но я все еще верю, что модель просмотра может быть протестирована, даже если она всплывает из окон. Все, что нам нужно, это просто использовать окно с инициализированным контентом с необходимой моделью просмотра. Я думаю, может быть две возможные ситуации, когда виртуальная машина должна открыть новый диалог: либо показать окно параметров/настроек, либо показать окно, которое зависит от бизнес-логики. В первом случае новый оконный код является единственным кодом команды (команда для кнопки «Настройки» или «Параметры»/пункт меню). Во втором случае у нас есть логика принятия решений, которая открывает окно. Но в любом случае мы можем переместить код, который открывает новое окно в отдельный метод/класс, и при тестировании нашей виртуальной машины просто для издевательства над этим методом/классом. Более того, этот отдельный класс может быть своего рода родовым WindowsController, который будет отслеживать все окна в приложении. Но все же мы можем сказать, что модель просмотра открывает всплывающее окно, используя вспомогательный WindowsController, и представление ничего не знает о других окнах. Вся бизнес-логика остается инкапсулированной в модель и модель представления.

0

Имейте ViewModel для всплывающих окон и просмотра в качестве пользовательского элемента управления. В зависимости от сложности всплывающего окна это может быть универсальная виртуальная машина или конкретная виртуальная машина для бизнес-кейса. При попытке отобразить его из родительской виртуальной машины создайте класс «хозяин» для виртуальной машины popups (унаследованной от окна или всплывающего окна), покажите ее и назначьте ей VM. Хост должен нести ответственность за правильное представление местоположения (например, через DataTemplate)

В этом случае виртуальная машина вашего всплывающего окна по-прежнему проверяется, и минимальный уровень связи с WPF для родительской VM является приемлемым, ИМО.

2

Отъезд Onyx. Это библиотека M-V-VM (полное раскрытие: я автор), основанный на использовании сервисов и шаблонах инсталляции Service Locator или Dependency Injection. Существуют службы для MessageBox и общих диалогов, и довольно легко добавить свои собственные услуги.

 Смежные вопросы

  • Нет связанных вопросов^_^