Подтвердить что ты не робот

WPF Prism - Какой смысл использовать регионы Призма?

Мне просто интересно, в чем суть регионов. Я думаю, Я не понимаю проблему, которую они решают.

Например, я вижу много людей, использующих регионы для области навигации, но почему бы не просто привязать элемент ItemsControl к ObservableCollection, а не обладать областью и загрузить в разные навигационные элементы в этот регион?


Реальный пример использования/преимуществ над альтернативами будет качать!

4b9b3361

Ответ 1

Сравните RegionManager с EventAggregator, и вы увидите его преимущество...

EventAggregator позволяет различным компонентам публиковать/подписываться на события, не будучи связанными друг с другом. То же самое происходит с RegionManager... вы можете загрузить представление в регион без вашего другого представления, зная, что там происходит. Он отделяет ваши взгляды друг от друга... чтобы не говорить КАЖДЫЙ вид не должен был знать друг о друге... бывают моменты, когда представление должно знать о другом представлении.


Посмотрите на Microsoft Outlook (примечание: я делаю все здесь, включая имена, поскольку Outlook является not, написанным в WPF, но вместо этого С++):

Основной пользовательский интерфейс будет иметь следующие области:

  • MenuRegion
  • NavigationRegion
  • ContentRegion
  • SideRegion

Регионы определяются стандартными элементами управления (поэтому вам все еще требуются стандартные элементы управления), а точнее ItemsControl, ContentControl и Selector из коробки (вы можете расширить другие элементы управления, чтобы быть "поддержкой региона" ). Они позволяют другому разделу кода управлять регионами, разрешая и загружая соответствующие представления в эти регионы. В принципе, чтобы все было отделено.

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

Итак, как это происходит на самом деле? Здесь сценарий: щелкните значок календаря в элементе управления навигацией. Итак, что должно произойти, когда вы это сделаете?

  • NavigationView - кнопка (значок) привязана к ICommand, поэтому она вызывает функцию ExecuteLoadCalendar().
  • NavigationViewModel - Функция ExecuteLoadCalendar() использует EventAggregator, чтобы объявить, что пользователь пытается запустить календарь.
  • ContentController - ContentController подписался на LoadCalendarAggregateEvent, так что это выполняется. Здесь он разрешает/активирует CalendarView (COUPLED) с помощью IRegionManager и имени региона. Он должен сделать это, захватив ICalendarView вместо CalendarView.

На протяжении всего процесса каждая часть разделяется, за исключением ContentController и CalendarView/ICalendarView. Конечно, можно сказать, что тип NavigationView/NavigationViewModel знал о CalendarView/CalendarViewModel с помощью ICommand и функции. Ну, "вид" - это не то же самое, что "они делают", потому что код кода и код модели не должны ссылаться на фактические объекты CalendarView/CalendarViewModel.

Кроме того, мы можем удалить "вид", выполнив родовое исполнение. Вместо функции ExecuteLoadCalendar() она может иметь функцию LoadContent(NavigationItem item), где полезная нагрузка AggregateEvent является идентификацией какого-либо типа, например item.Name (String) (загружается из БД, XML и т.д.), Чтобы заявить, что они нажмите "Календарь". ContentController использует те же данные для разрешения "Календарь" вместо ICalendarView (потому что на самом деле ему все равно, какой интерфейс/тип разрешен/активирован в ContentRegion - ему просто нужен объект для активации), Я использую MEF, поэтому это может быть достигнуто с помощью следующего кода:

[Export("Calendar")]
public class CalendarView : UserControl, ICalendarView { }

Итак, могут ли представления узнать друг о друге? Да! Например, у моего EmailUserControl есть панель поиска/список писем, а также панель предварительного просмотра. Эти 2 элемента управления могут быть EmailListUserControl, который состоит из панели поиска и элемента управления ItemsControl и EmailContentUserControl, которая представляет собой панель предварительного просмотра для выбранного сообщения. Должны ли они быть отдельным контролем? Нет, но если это так, мы можем повторно использовать EmailContentUserControl, когда мы открываем письмо в отдельном окне. Итак, это пример, когда EmailUserControl связан с двумя разными представлениями (EmailListUserControl и EmailContentUserControl).


Почему это лучше/отличается от других подходов: Он отделяет представления друг от друга (и защищает от просмотра моделей, которые должны знать о представлениях).

Ответ 2

Регионы позволяют определить место в вашей программе, которое существует для определенной цели. Например, у вас может быть область меню или нижний колонтитул. Затем вы можете разделить Views/ViewModels для этих конкретных регионов на свой раздел программы.

Таким образом, вместо наличия ApplicationViewModel содержащих свойств для MenuViewModel и FooterViewModel, и имея вид привязать каждый раздел к этим свойствам, у вас будут отдельные ViewModels для меню и нижнего колонтитула, и ваш ApplicationViewModel будет иметь дело только с с содержанием. Это лучший способ отделить некоторые логические ограничения в вашем приложении.

Лично я думаю, что Регионы ужасно злоупотребляют и злоупотребляют. Я почти никогда их не использую, если у меня есть что-то вроде заголовка или нижнего колонтитула, не связанного с остальной частью моего кода приложения. Они также в основном используются в разработке View-First, и я предпочитаю ViewModel-First.

Ответ 3

Сценарии, в которых область разрешает

Я снял эту статью, чтобы получить ответ: http://www.developmentalmadness.com/archive/2009/10/14/mvvm-and-prism-101-ndash-part-3-regions.aspx

Насколько я могу судить, функция Region предназначена для включения просмотра регистрации/вставки в код, который не является ни вашим представлением, ни вашей моделью просмотра.

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

Если вы использовали ItemsControl и привязывали его к произвольным данным в модели представления, вам нужно будет указать, какие представления должны быть созданы в DataTemplate на главном представлении.

В Регионе вы можете зарегистрировать представление в регионе в контейнере Dependency Injection. Ни вид, ни соответствующие модели представления не должны знать ничего о конкретном представлении, которое будет использоваться во время выполнения. Он будет впрыскиваться в контейнер.

Это позволяет полностью отделить основное представление от знания чего-либо о его дочерних представлениях, не заставляя вашу модель представления ничего знать о этих дочерних представлениях.

Конкретные варианты использования

Насколько это полезно и какие конкретные сценарии это позволит, я не уверен. Я использовал ContentPresenter с плагиновой архитектурой, но я не уверен, что подходит этой модели. С помощью модели плагина вы хотите, чтобы модель представления и представления была связана вместе, поэтому этот подход ничего не покупает.

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

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