MVVM Pattern в шаблонной форме - PullRequest
3 голосов
/ 30 июля 2011

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

Теперь я вижу, что нарушаю шаблон MVVM для этого требования. Вот почему ... 1. ViewModel может читать шаблон из базы данных, захватывать представления (используя MEF), но чтобы добавить их в форму, ему необходимо знать имя сетки макета и добавить представления в качестве дочернего элемента этой сетки. Это все равно, что рассказывать ViewModel об элементах пользовательского интерфейса, что противоречит шаблону проектирования MVVM.

  1. Для «обязательных» представлений, которые должны отображаться во всплывающем окне, viewModel потребуется создать экземпляр ChildWindow, добавить в него «требуемые» представления и затем показать Childwindow. Также обрабатывает закрытые / закрывающие события.

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

Спасибо. A

Ответы [ 3 ]

3 голосов
/ 30 июля 2011

ИМХО: Это еще одна ситуация, когда простое добавление контроллеров в MVVM решит все проблемы без проблем.Мы называем это MVCVM (позор, который не соответствует действительным римским цифрам):)

Шаблон, который мы успешно используем во всех недавних проектах, заключается в регистрации контроллеров только в модулях и инициализацииих при запуске.Контроллеры очень легкие / тонкие, и единственное, что нужно для работы приложения , для прослушивания или отправки сообщений .В своих методах инициализации они затем регистрируют все, что им нужно (представления и модели представления и т. Д.).Этот легкий шаблон логики «только в памяти» также подходит для более тонких приложений (например, лучше для WP7).

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

Основные правила, которым мы следуем:

  • Контроллеры принимают решения на основе событий
  • Контроллеры извлекают данные и помещают их в соответствующие свойства View Model
  • Контроллеры устанавливают свойства ICommand моделей View для перехвата событий
  • Контроллеры позволяют отображать представления (если не указано в другом месте)
  • ViewМодели "тупые".Удерживаемые данные для привязки и ничто иначе
  • Представления знают, что они отображают определенную форму данных, но не имеют представления, откуда они берутся

Последние дваточки - это те, которые вы никогда не должны нарушать, или разделение интересов выходит за пределы окна.

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

Подумайте об этом.Вы можете (повторно) представить контроллеры своим приложениям MVVM.Если вам нужна дополнительная информация, просто спросите.

0 голосов
/ 31 июля 2011

Вот решение, которое приходит мне в голову.

1. Декорирование моделей представления с метатегами, которые носят имя представления, с которым связана модель представления.

  1. Создайте новый класс с именем ViewViewModel, который содержит два свойства

    • Имя представления
    • Экземпляр ViewModel.
  2. В форме ViewModel, которая отвечает за объединение всех видов вместе, а также вызывает дочернее окнов зависимости от случая.Добавьте три свойства

    • Список FormViews
    • Список ChildWindowViews.
    • Действие ShowChildWindow

Модель FormView будетсоздавать экземпляры требуемых моделей представления, собирать имя представления из каждой модели представления из метатега MEF и заполнять свойства FormView и ChildWindowView.Как только форма ViewModel формы обработает запрос и два свойства заполнены, она запускает делегат ShowWindow с параметром true, если ChildWindow не пуст.

  1. Представление формы выполнит следующее

    • Корень Layout будет иметь панель стека, связанную со свойством FormView.Будет IValueConverter, который обрабатывает каждую запись в списке FormViews.Для каждого ViewName он находит и создает представление вида.Устанавливает для DataContext значение ViewModel.

    • Когда вызывается действие ShowChildWindow, в представлении формы существует минимальный программный код, который создает и показывает ChildWindow, связанный со свойством ChildWindowViews.Свойство ChildWindow использует тот же IValueCOnverter для создания экземпляров запрошенных представлений.

Как это звучит?Просьба комментировать

enter code here
0 голосов
/ 31 июля 2011

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

Если у вас есть свобода использования MVVM-фреймворка, вы можете попробовать что-то вроде PRISM или MVVMLight. Prism предлагает согласователь событий, в то время как MVVMLight предлагает классы Messenger, которые могут отделить связь между представлением и моделью представления, а также различными моделями представления.

...