Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Начальство разработчика Prism — часть 8.1, навигация на основе представлений (View-Based Navigation)

Anna | 18.06.2014 | нет комментариев

Невзирая на то, что навигация на основе состояний может быть пригодна в сценариях, описанных ранее, тем не менее, навигация в приложении Зачастую требует замены одного представления на другое. В Prism, такой вид навигации именуется «навигация на основе представлений (view-based navigation)».

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

  • Цель навигации — контейнер для добавляемых, либо удаляемых представлений — может обрабатывать навигацию различными методами при добавлении и удалении представлений, либо может визуализировать процесс навигации по-различному. Во многих случаях, целью навигации является обыкновенный Frame, либо ContentControl, и представления легко отображаются внутри этих элементов управления. Впрочем существует уйма сценариев, когда целью навигации является иной вид элементов управления, таких как TabControl, либо ListBox. В таких случаях, навигация может затребовать активизации либо выделения теснее присутствующего представления, либо добавление нового представления.
  • Приложению Зачастую будет требоваться, каким-либо образом идентифицировать представление, к которому должна быть исполнена навигация. Для примера, в web-приложениях, страница, к которой выполняется навигация, напрямую идентифицируется по URI. В клиентских приложениях, представление может быть идентифицировано по имени его типа, по расположению файла источников, либо большинством других методов. В комбинированных приложениях, состоящих из слабо связанных модулей, представления нередко определены в раздельных модулях. Отдельные представления, в таких случаях, обязаны иметь вероятность быть идентифицированы без создания дополнительных зависимостей между модулями.
  • Позже идентификации представления, процесс его создания и инициализации должен быть скрупулезно скоординирован. Это исключительно значимо при применении паттерна MVVM. В таком случае, представления и соответствующая модель представления обязаны быть сделаны и ассоциированы друг с ином во время совершения навигации. В случае применения контейнера внедрения зависимостей, такого как Unity, либо MEF, при создании модели представления и/или представления может понадобиться применение специального механизма конструирования.
  • MVVM паттерн разрешает отделить UI приложения от его логики взаимодействия с пользователем и бизнес-логики. Впрочем процесс навигации может охватывать как UI, так и логику приложения. Пользователь может начать навигацию внутри представления, в итоге чего представление будет обновлено. Но Зачастую будет требоваться вероятность инициировать и скоординировать навигацию из модели представления. Значимым аспектомдля рассмотрения, является способность чётко поделить навигационное поведение между представлением и моделью представления.
  • Приложению Зачастую может понадобиться передавать параметры, либо контекст, представлению для его правильной инициализации. Для примера, если пользователь изготавливает навигацию к представлению для редактирования информации о выбранном заказчике, ID этого заказчика, либо его данные, обязаны быть переданы в представление, для отображения в нем правильной информации.
  • Многим приложениям нужно скрупулезно координировать навигацию для уверенности, что будут исполнены определённые бизнес-требования. К примеру, пользователю может быть показано всплывающее сообщение о некорректности введённых им данных, во время попытки навигации к иному представлению. Данный процесс требует координации между предыдущим и новым представлениями.
  • Наконец, множество современных приложений разрешают пользователю изготавливать навигацию к предыдущему, либо к дальнейшему представлению. Подобно, некоторые приложения реализуют свой рабочий процесс, применяя последовательность представлений, либо форм и разрешают пользователю изготавливать по ним навигацию вперёд либо назад, добавляя либо редактируя данные, перед тем, как закончить задачу и отправить все сделанные метаморфозы одним пакетом. Такие сценарии требуют некоторого механизма журналирования, для того, Дабы последовательность навигации могла быть сохранена, повторена, либо предопределена.

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

Обзор регионов (Region) Prism

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

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

<ContentControl prism:RegionManager.RegionName="MainRegion" ... />

Для всякого элемента управления, определённого как регион, Prism создаёт объект Region (регион), представляющий сам регион, и объект RegionAdapter (адаптер региона), задачей которого является управление расположением и активизацией представлений в заданном элементе управления. Prism Library предоставляет реализацию RegionAdapter для большинства элементов управления Silverlight и WPF. Вы можете сделать свой личный RegionAdapter для поддержки дополнительных элементов управления, либо для реализации специального поведения. Класс RegionManager (администратор регионов) предоставляет доступ к объектам Region приложения.

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

Адаптер региона управляет списком представлений, ассоциированных с этим регионом. Одно, либо несколько из этих представлений, могут быть отображены в элементе управления региона, в соответствии с его стратегией отображения содержимого. Представлениям могут быть назначены имена, которые могут быть использованы для их поиска в последующем. Адаптер региона также управляет тем, какое представление является энергичным в данном регионе. Энергичным, является то представление, которое выделено в данный момент, либо является самым верхним. К примеру, в TabControl, энергичным является то представление, которое отображено на выделенной вкладке, в ContentControl — то, которое отображается на экране в данный момент.

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

Предыдущие версии Prism разрешали отображать представления в регионах двумя разными методами. 1-й метод, называемый внедрение представления (view injection), разрешал программно отображать представления в регионе. Данный подход пригоден при отображении динамического оглавления, когда представление, которое нужно отобразить в регионе, Зачастую изменяется, отображая логику приложения.

Внедрение представлений поддерживается через предоставление способа Add в классе Region. Дальнейший код показывает, как вы можете получить ссылку на объект Region через класс RegionManager, и программно добавить в него представление. В примере, представление создаётся с поддержкой DI контейнера.

IRegionManager regionManager = ...;
IRegion mainRegion = regionManager.Regions["MainRegion"];
InboxView view = this.container.Resolve<InboxView>();
mainRegion.Add(view);

Дальнейший способ, называемый выявление представления (view discovery), разрешает модулям регистрировать сравнение типов представлений с именами регионов. В момент, когда регион с заданным именем будет отображён на экране, будет механически сделан экземпляр соответствующего представления и отображён в этом регионе. Данный поход пригоден для отображения относительно статического оглавления, когда представление, отображённое в регионе, не меняется.

Выявление представления поддерживается через способ RegisterViewWithRegion в классе RegionManager. Данный способ разрешает задать способ обратного вызова, тот, что будет вызван при отображении региона с заданным именем. Дальнейший пример показывает, как дозволено сделать представление (использую контейнер внедрения зависимостей) при отображении региона с именем «MainRegion».

IRegionManager regionManager = ...;
regionManager.RegisterViewWithRegion("MainRegion", () => container.Resolve<InboxView>());

Для больше подробного обзора регионов Prism, глядите главу “Создание пользовательского интерфейса“. Дальше в статье будут рассмотрено, как регионы были расширены для поддержки навигации, и как одолеть описанные ранее задачи.

Базовая навигация в регионах

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

Навигация в пределах региона обозначает отображение нового представления в нём. Отображаемое представление идентифицируется с поддержкой URI, тот, что, по умолчанию, ссылается на имя представления, к которому осуществляется навигация. Вы можете инициировать навигацию программно, применяя способ RequestNavigate, определённый в интерфейсе INavigateAsync.

Заметка.
Невзирая на наименование, интерфейс INavigateAsync не подразумевает асинхронную навигацию, исполняемую в отдельном потоке. Напротив, INavigateAsync подразумевает проведение псевдо-асинхронной навигации. Способ RequestNavigate может кончаться синхронно, позже окончания навигации, либо он может кончаться до окончания навигации, скажем, когда пользователю необходимо удостоверить навигацию. Дозволяя вам задавать способ обратного вызова во время навигации, Prism даёт вероятность поддержки таких сценариев без трудностей обращения с фоновыми потоками.

Интерфейс INavigateAsync реализует класс Region, разрешая инициировать навигацию в этом регионе.

IRegion mainRegion = ...;
mainRegion.RequestNavigate(new Uri("InboxView", UriKind.Relative));

Вы также можете вызвать способ RequestNavigate на объекте RegionManager, задав имя региона, на котором производится навигация. Данный способ находит ссылку на соответствующий регион и вызывает на нём способ RequestNavigate. Это показано на примере ниже.

IRegionManager regionManager = ...;
regionManager.RequestNavigate("MainRegion", new Uri("InboxView", UriKind.Relative));

По умолчанию, навигационный URI задаёт имя представления, по которому оно зарегистрировано в контейнере. Код ниже иллюстрирует взаимоотношения между именем регистрации представления в контейнере Unity и применения этого имени во время навигации.

container.RegisterType<object, InboxView>("InboxView");
regionManager.Regions[Constants.MainRegion].RequestNavigate(new Uri("InboxView", UriKind.Relative));

Заметка.
При создании представления навигационным сервисом, он запрашивает объект тип Object из контейнера, с именем, предоставленном в навигационном URI. Разные контейнеры применяют разные механизмы регистрации для поддержки этого. К примеру, в Unity, вам необходимо зарегистрировать представления, сопоставив тип Object с этим представлением, и предоставив имя регистрации, соответствующее имени в навигационном URI. В MEF необходимо каждого лишь задать имя контракту в признаке ExportAttribute.

Пример. При применении Unity для регистрации представления:

Не используйте:

container.RegisterType<InboxView>("InboxView");

Используйте взамен этого:

container.RegisterType<object,InboxView>("InboxView");

Заметка.
Имя, используемое для регистрации и навигации, не непременно должно быть связано с именем типа представления, подойдёт любая строка. Для примера, взамен строки, вы можете очевидно применять полное имя типа: typeof(InboxView).FullName;

В MEF, вы легко можете экспортировать представление с требуемым именем.

[Export("InboxView")]
public partial class InboxView : UserControl { ... }

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

Заметка.
Предшествующее изложение иллюстрирует view-first навигацию, когда URI ссылается на имя представления, с которым оно было экспортировано либо зарегистрировано в контейнере. С view-first навигацией, зависимая модель представления создаётся как связанность представления. Альтернативным подходом является применение view model–first навигацию, когда навигационный URI ссылается на имя модели представления, с которым она была зарегистрирована в контейнере. Такой подход может быть пригоден, когда представления определены, как образцы данных, либо когда вы хотите, Дабы схема навигации была определена самостоятельно от представлений.

Способ RequestNavigate также разрешает задать способ обратного вызова, тот, что будет вызван при заключении навигации.

private void SelectedEmployeeChanged(object sender, EventArgs e) {
    ...
    regionManager.RequestNavigate(RegionNames.TabRegion, "EmployeeDetails", NavigationCompleted);
}

private void NavigationCompleted(NavigationResult result) {
    ...
}

Класс NavigationResult имеет свойства, через которые дозволено получить информацию о навигационной операции. Качество Result показывает, завершилась ли навигация. Если навигация завершилась с оплошностью, то качество Error будет содержать ссылку на всякие исключения, вброшенные во время навигации. Через качество Context дозволено получить доступ к навигационному URI и любым параметрам, которые он содержит, а также к ссылке на сервис, координирующий навигационные операции.

Участие представления и модели представления в навигации

Зачастую бывает, что и представление, и модель представления в вашем приложении захотят принять участие в навигации. Сделать это разрешает интерфейс INavigationAware. Вы можете реализовать данный интерфейс в представлении, либо (больше Зачастую) в модели представления. Реализовав его, ваше представление, либо модель представления могут принять непосредственное участие в процессе навигации.

Заметка.
В дальнейшем изложении делается предположение, что навигация происходит между представлениями. Но необходимо подметить, что интерфейс INavigationAware во время навигации будет вызываться вне зависимости от того, реализован ли он в представлении, либо в модели представления. Во время навигации, Prism проверяет, реализует ли представлениеINavigationAware, если да, то на нём вызываются нужные способы. Также, Prism делает проверку реализации этого интерфейса на объекте, в тот, что установлено качество DataContextпредставления, и, в случае триумфа, вызывает нужные способы.

Данный интерфейс разрешает представлению, либо модели представления принять участие в операции навигации. В интерфейсе INavigationAware определены три способа:

public interface INavigationAware {
    bool IsNavigationTarget(NavigationContext navigationContext);
    void OnNavigatedTo(NavigationContext navigationContext);
    void OnNavigatedFrom(NavigationContext navigationContext);
}

Способ IsNavigationTarget разрешает присутствующему в регионе представлению, либо модели представления, показать, может ли оно обработать запрос навигации. Это может быть пригодным в случаях, когда вы хотите вторично применять теснее существующее представление для обработки навигации, либо хотите совершить навигацию к теснее присутствующему представлению. Для примера, представление, отображающее информацию о заказчике, может обновляться при выборе разных заказчиков. Для приобретения больше подробной информации, глядите раздел «Навигация к присутствующим представлениям» дальше в статье.

Способы OnNavigatedFrom и OnNavigatedTo вызываются во время операции навигации. Если нынешнее энергичное представление в регионе (либо его модель представления) реализует данный интерфейс, способOnNavigatedFrom вызывается до начала навигации. Способ OnNavigatedFrom разрешает предыдущему представлению сберечь своё состояние, либо подготовиться к деактивации либо удалению из пользовательского интерфейса. Для примера, представление может сберечь сделанные пользователем метаморфозы в базу данные, либо отослать их web-сервису.

Если только что сделанное представление (либо модель представления) реализует данный интерфейс, его способ OnNavigatedTo вызывается позже совершения навигации. Способ OnNavigatedTo разрешает только что отображённому представлению провести инициализацию, допустимо, применяя параметры, переданные совместно с навигационным URI. Для приобретения дополнительной информации, глядите дальнейший раздел «Передача параметров во время навигации».

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

public class EmployeeDetailsViewModel : IRegionMemberLifetime {
    public bool KeepAlive { get { return true; } }
}

Интерфейс IRegionMemberLifetime определяет исключительное качество KeepAlive, доступное только для чтения. Если оно установлено в false, представление будет удалено из региона при его деактивации. Так как регион позже этого перестаёт беречь ссылку на представление, оно будет достигаемо для сборщика мусора (если, безусловно, на него не ссылаются другие части вашего приложения). Вы можете реализовать данный интерфейс, как в представлении, так и в модели представления. Правда интерфейс IRegionMemberLifetimeпредуготовлен, по большей части, для управления временем жизни представлений в регионах во время активизации и деактивации, качество KeepAlive также применяется во время навигации позже создания и активизации представления в целевом регионе.

Заметка.
Регионы, способные отображать несколько представлений, такие как ItemsControl, либоTabControl, будут показывать как энергичные, так и неактивные представления. Удаление неактивного представления из региона, для этих элементов управления, приведёт к удалению его из пользовательского интерфейса.

Передача параметров во время навигации

Для реализации нужного поведения при навигации, вам нередко может потребоваться задавать добавочные данные, передаваемые во время запроса навигации, помимо имени целевого представления. ОбъектNavigationContext предоставляет доступ к навигационному URI и ко каждому параметрам, которые были переданы совместно с ним. Вы можете получить доступ к NavigationContext в способах IsNavigationTarget,OnNavigatedFrom, и OnNavigatedTo.

Для помощи в задании и приобретении параметров навигации, в Prism существует класс UriQuery. Вы можете применять его при необходимости добавить навигационные параметры к URI перед началом навигации и для доступа к этим параметрам во время навигации. UriQuery создаёт список с парами имя-значение для всякого параметра.

Дальнейший пример кода показывает, как добавить параметры к UriQuery и присоединить их к навигационному URI.

Employee employee = Employees.CurrentItem as Employee;
if (employee != null) {
    UriQuery query = new UriQuery();
    query.Add("ID", employee.Id);
    _regionManager.RequestNavigate(RegionNames.TabRegion,
        new Uri("EmployeeDetailsView"   query.ToString(), UriKind.Relative));
}

Вы можете получить навигационные параметры, применяя качество Parameters объекта NavigationContext. Это качество возвращает экземпляр класса UriQuery, у которого есть качество-индексатор для облегчения доступа к индивидуальным параметрам.

public void OnNavigatedTo(NavigationContext navigationContext) {
    string id = navigationContext.Parameters["ID"];
}

Навигация к присутствующим представлениям

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

Примером к первому сценарию может служить обстановка, когда приложению разрешает пользователю изменять информацию о заказчике, применяя представление EditCustomer, и пользователь теснее использует это представление для редактирования заказчика с ID 123. Если пользователь решит отредактировать запись о заказчике с ID 456, он может легко совершить навигацию к представлению EditCustomer и ввести новейший ID. Позже этого, представление EditCustomer запросит данные о новом заказчике и обновит свой UI соответствующим образом.

Для примера применения второго сценария, возможен, что приложение разрешает редактировать информацию сразу о нескольких заказчиках единовременно. В этом случае, приложение отображает несколько представлений EditCustomer в TabControl, к примеру, заказчиков с ID 123 и ID 456. При навигации кEditCustomer и вводе ID 456, соответствующее представление будет активировано (то есть, соответствующая вкладка будет выделена). Если пользователь совершит навигацию к представлениюEditCustomer и введёт ID 789, то новейший экземпляр будет сделан и отображён в UI.

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

Prism поддерживает оба описанных выше сценария через способ INavigationAware.IsNavigationTarget. Данный способа вызывается во время навигации на представлениях в регионе, имеющих тот же тип, что и целевое представление. В предыдущем примере, целевое представление было типа EditCustomer, следственно способ IsNavigationTarget будет вызван на всех существующих представлениях типаEditCustomer, находящихся в регионе. Prism определяет целевой тип представления с поддержкой навигационного URI, полагая, что он является коротким именем типа целевого представления.

Заметка.
Для того, Дабы Prism определила тип целевого представления, имя представления в навигационном URI должно соответствовать короткому имени его типа. К примеру, если представление имеет класс MyApp.Views.EmployeeDetailsView, то имя представления, заданное в навигационном URI должно быть EmployeeDetailsView. Это является стандартным поведением Prism. Вы можете изменить его, сделав свой класс загрузчика контента. Сделать это дозволено реализовав интерфейс IRegionNavigationContentLoader, либо унаследовав свой класс отRegionNavigationContentLoader.

Реализация способа IsNavigationTarget может применять параметр NavigationContext для определения, может ли представление обработать навигационный запрос. NavigationContext даёт доступ к навигационному URI и навигационным параметрам. В предыдущем примере, реализация этого способа в модели представленияEditCustomer, сопоставляла нынешний ID заказчика с ID, заданном в навигационном запросе, возвращая trueпри совпадении.

public bool IsNavigationTarget(NavigationContext navigationContext) {
    string id = navigationContext.Parameters["ID"];
    return _currentCustomer.Id.Equals(id);
}

Если способ IsNavigationTarget неизменно возвращает true, вне зависимости от навигационных параметров, это представление неизменно будет применяться вторично. Такой подход может гарантировать, что в определённом регионе будет существовать только одно представление определённого типа.

Доказательство, либо отмена навигации

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

Интерфейс IConfirmNavigationRequest унаследован от интерфейса INavigationAware и добавляет способConfirmNavigationRequest. Реализуя данный интерфейс в вашем представлении, либо модели представления, вы дозволяете им участвовать в процессе навигации, разрешая взаимодействовать с пользователем так, Дабы он мог отменить, либо удостоверить навигацию. Вам также может потребоваться применять объект Interaction Request, о котором было рассказано в части 6 “Продвинутые сценарии MVVM“, для показа всплывающего окна с подтверждением.

Заметка.
Способ ConfirmNavigationRequest вызывается на энергичном представлении (либо модели представления), подобно способу OnNavigatedFrom, описанному ранее.

Способ ConfirmNavigationRequest принимает два параметра, ссылку на нынешний навигационный контекст, описанный выше, и делегат, тот, что нужно будет вызвать для продолжения навигации. По этой причине, данный делегат Зачастую называют делегатом-продолжением (continuation callback). Вы можете сберечь ссылку на делегат-продолжение, для его вызова позже окончания взаимодействия с пользователем. Если приложение взаимодействует с пользователем через объекты Interaction Request, вы можете применять данный делегат в качестве способа обратного вызова запроса взаимодействия. Дальнейшая диаграмма иллюстрирует полный процесс.

Подтверждение навигации, используя объект запроса взаимодействия

Следующие шаги описывают процесс подтверждения навигации при применении объекта InteractionRequest:

  1. Навигация инициируется через вызов способа RequestNavigate.
  2. Если представление, либо модель представления реализуют интерфейс IConfirmNavigation, вызывается способа ConfirmNavigationRequest.
  3. Модель представления вызывает событие начала взаимодействия (interaction request event).
  4. Представление отображает всплывающее окно с подтверждением и ждёт результата от пользователя.
  5. Способ обратного вызова запроса взаимодействия вызывается позже того, как пользователь закрывает всплывающее окно.
  6. Делегат-продолжение вызывается для продолжения, либо отмены прекращенной операции навигации.
  7. Операция навигации завершается, либо отменяется.

Дабы увидеть иллюстрацию этому, посмотрите View-Switching Navigation Quick Start. Это приложение разрешает пользователю создавать сообщения электронной почты, применяя классы ComposeEmailView, иComposeEmailViewModel. Класс модели представления реализует интерфейс IConfirmNavigation. Если пользователь делает навигацию, к примеру, нажимая кнопку Calendar, в время создания сообщения, будет вызван способ ConfirmNavigationRequest для того, Дабы модель представления могла запросить доказательство у пользователя. Для поддержки этого, модель представления задаёт объект запроса взаимодействия, как показано в примере ниже.

public class ComposeEmailViewModel : NotificationObject, IConfirmNavigationRequest {
    private readonly InteractionRequest<Confirmation> confirmExitInteractionRequest;

    public ComposeEmailViewModel(IEmailService emailService) {
        this.confirmExitInteractionRequest = new InteractionRequest<Confirmation>();
    }

    public IInteractionRequest ConfirmExitInteractionRequest { get { return this.confirmExitInteractionRequest; } }
}

В классе ComposeEmailVew задан триггер InteractionRequestTrigger, привязанный к свойствуConfirmExitInteractionRequest модели представления. При запросе взаимодействия, пользователю показывается примитивное всплывающее окно.

<UserControl.Resources>
    <DataTemplate x:Name="ConfirmExitDialogTemplate">
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}"/>
    </DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
    <ei:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmExitInteractionRequest}">
            <prism:PopupChildWindowAction ContentTemplate="{StaticResource ConfirmExitDialogTemplate}"/>
        </prism:InteractionRequestTrigger>
    </ei:Interaction.Triggers>
...

Способ ConfirmNavigationRequest класса ComposeEmailVewMode вызывается при попытке пользователя совершить навигацию во время написания сообщения. Реализация этого способа вызывает запрос взаимодействия, определённый ранее, так, Дабы пользователь мог удостоверить, либо изменить операцию навигации.

void IConfirmNavigationRequest.ConfirmNavigationRequest(
          NavigationContext navigationContext, Action<bool> continuationCallback) {
    this.confirmExitInteractionRequest.Raise(
            new Confirmation {Content = "...", Title = "..."},
            c => {continuationCallback(c.Confirmed);});
}

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

Заметка.
Необходимо подметить, что позже вызова способа Rise обpermark! … private IRegionNavigationService navigationService; public void OnNavigatedTo(NavigationContext navigationContext) { navigationService = navigationContext.NavigationService; } public DelegateCommand<object> GoBackCommand { get; private set; } private void GoBack(object commandArg) { if (navigationService.Journal.CanGoBack) { navigationService.Journal.GoBack(); } } private bool CanGoBack(object commandArg) { return navigationService.Journal.CanGoBack; } }
Вы можете сделать свой личный журнал для региона для реализации специфичного рабочего процесса для этого региона.

Заметка.
Навигационный журнал может применяться только в операциях навигации в регионе, которые координируются навигационным сервисом региона. Если вы используете технику выявления либо внедрения представления для реализации навигации в регионе, навигационный журнал не будет обновляться во время навигации и его невозможно применять для навигации назад, либо вперёд в регионе.

Применение WPF и Silverlight Navigation Frameworks

Навигация на основе регионов в Prism была спроектирована для поддержки большого диапазона сценариев и задач, которые вы можете встретить при реализации навигации в слабо связанных модульных приложениях, использующих паттерн MVVM и контейнер внедрения зависимостей, такой как Unity, либо MEF. Также, она была спроектирована для поддержки подтверждения и отмены навигации, навигации к присутствующим представлениям, передачи параметров во время навигации и ведения журнала навигации.

Поддерживая навигацию для регионов, Prism предоставляет вероятность совершения навигации внутри множества элементов управления, и даёт вероятность изменять разметку пользовательского интерфейса приложения, не нарушая конструкции навигации. Также поддерживается псевдо-синхронная навигация, что разрешает изготавливать расширенное взаимодействие с пользователем во время навигации.

Впрочем Prism навигация не была спроектирована для замены Silverlight navigation framework(представленного в Silverlight 3.0), либо WPF’s navigation framework. Взамен этого, навигация в регионах Prism была спроектирована для работы совместно с Silverlight и WPF navigation frameworks.

Silverlight navigation framework предоставляет поддержку больших ссылок, интеграция с браузером и проекцию навигационных URI. Навигация допустимо внутри элемента управления FrameFrameможет при необходимости отображать адресную строку, которая разрешает пользователю делать навигацию назад, либо вперёд между представлениями, отображаемыми в Frame. Обыкновенным подходом является применение Silverlight navigation framework для реализации высокоуровневой навигации в оболочке приложения и применение навигации Prism для всех остальных частей приложения. В таком случае, ваше приложение будет поддерживать большие ссылки и будет интегрировано с журналом браузера и его адресной строкой, а также будет пользоваться всеми превосходствами навигации в регионах Prism.

WPF navigation framework не является таким расширяемым, как в Silverlight. Соответственно, помощь внедрения зависимостей и образца MVVM значительно затрудняется. Он также базируется на элементе управления Frame, имеющем схожую функциональность, с точки зрения журналирования и навигационного UI. Вы можете применять WPF navigation framework совместно с навигацией Prism, правда, реализация навигации, применяя только регионы Prism, допустимо, будет больше простым и эластичным решением.

Последовательность навигации в регионе

Дальнейшая иллюстрация даёт обзор последовательности операций во время навигации. Она даётся как справка, Дабы вы могли видеть, как разные элементы навигации Prism взаимодействую друг с ином во время запроса навигации.

Последовательность навигации в регионе

Добавочная информация

Для приобретения дополнительной информации о Visual State Manager, глядите «VisualStateManager Class» на MSDN: http://msdn.microsoft.com/en-us/library/cc626338(v=VS.95).aspx.

Для приобретения дополнительной информации об применении поведений Microsoft Expression Blend, глядите «Working with built-in behaviors» на MSDN: http://msdn.microsoft.com/en-us/library/ff724013(v=Expression.40).aspx.

Для приобретения дополнительной информации о создании поведений Microsoft Expression Blend, глядите «Creating Custom Behaviors» на MSDN: http://msdn.microsoft.com/en-us/library/ff724708(v=Expression.40).aspx.

Для приобретения дополнительной информации о Silverlight Navigation Framework, глядите «Navigation Overview» на MSDN: http://msdn.microsoft.com/en-us/library/cc838245(VS.95).aspx.

Для приобретения дополнительной информации об интеграции Silverlight’s Navigation Framework с Prism, глядите «Integrating Prism v4 Region Navigation with Silverlight Frame Navigation» в блоге Karl Schifflett’s: http://blogs.msdn.com/b/kashiffl/archive/2010/10/05/integrating-prism-v4-region-navigation-with-silverlight-frame-navigation.aspx.

Источник: programmingmaster.ru

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB