Должна ли ViewModel в MVVM ссылаться на View? - PullRequest
12 голосов
/ 08 сентября 2010

В шаблоне MVVM (Model-View-ViewModel) должен ViewModel ссылаться на представление. Я думаю, что это не должно. Но как использовать следующий сценарий? У меня есть представление, которое имеет элемент управления вкладками в качестве основного контейнера, модель представления для этого представления реализует команду для добавления новой вкладки в элемент управления вкладками. Самый простой способ - позволить модели представления ссылаться на представление, а затем в реализации команды просто программно добавить новую вкладку в tabcontrol в представлении. Это просто кажется неправильным. Должен ли я каким-то образом связать tabcontrol с viewmodel, а затем реализовать data / control-template для добавления новых вкладок. Я надеюсь, что для кого-то это имеет какой-то смысл:)

Ответы [ 4 ]

13 голосов
/ 08 сентября 2010

В «чистом» MVVM ViewModel не должен ссылаться на View. Тем не менее, часто бывает удобно предоставить интерфейс вида в представлении, с помощью которого ViewModel может взаимодействовать с ним.

Однако я обнаружил, что почти никогда не делаю этого больше. Альтернативный подход заключается в использовании какой-либо формы присоединенного свойства или смешанного поведения в вашем представлении и его привязке к свойствам ViewModel. Это позволяет вам сохранить логику просмотра на 100% в представлении. Кроме того, создавая поведение для этого, вы создаете тип для повторного использования , который можно использовать для обработки этого в каждом взаимодействии ViewModel-> View. Я настоятельно предпочитаю этот подход, чем иметь какую-либо логику View в ViewModel.

Чтобы продемонстрировать эту технику, я написал образец для галереи кодов выражений под названием WindowCloseBehavior . Он демонстрирует, как вы можете использовать поведение в представлении, привязанном к свойствам в модели представления, для управления жизненным циклом окна, включая предотвращение его закрытия и т. Д.

8 голосов
/ 08 сентября 2010

Рид и Дэн рассмотрели общий подход, но, ссылаясь на ваш конкретный случай, TabControl - это ItemsControl, поэтому он может привязать свой ItemsSource к коллекции данных в вашей ViewModel, представляющей набор вкладок для отображения.Пользовательский интерфейс для каждого типа вкладки затем может быть представлен в виде DataTemplate, определенного для типа данных элемента (с использованием DataType или DataTemplateSelector).Затем вы можете добавлять или удалять элементы данных по мере необходимости из вашей виртуальной машины и автоматически обновлять вкладки, при этом виртуальная машина ничего не знает о TabControl.

3 голосов
/ 08 сентября 2010

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

Использование интерфейса по-прежнему сохраняет View и ViewModel в значительной степени разъединенными и позволяет имитировать конкретный IView во время тестирования.

0 голосов
/ 14 января 2014

Один из нас упускает что-то очевидное.Элемент управления вкладки - это ItemsControl.Вам следует привязать ItemsSource элемента управления вкладки к коллекции ovservable в вашей модели представления.Когда вы обрабатываете команду в своей модели представления для добавления вкладки, вы просто добавляете новый элемент в эту коллекцию и, вуаля, вы добавляете новую вкладку в элемент управления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...