Оглавление
- Введение
- Инициализация приложений Prism
- Управление зависимостями между компонентами
- Разработка модульных приложений
- Реализация паттерна MVVM
- Продвинутые сценарии MVVM
- Создание пользовательского интерфейса
- Навигация
- Навигация на основе представлений (View-Based Navigation)
- Способы коммуникации между слабосвязанными компонентами
Во время взаимодействия с пользователем, UI приложения может подвергаться значительным изменениям, в зависимости от того, какие действия должен выполнять пользователь, и с какими данными он работает. Процесс, когда приложение координирует изменения пользовательского интерфейса, часто называют «навигацией (navigation)».
Зачастую, «навигация» означает, что одни элементы управления удаляются, а другие добавляются в пользовательский интерфейс. В других случает, это означает обновление вида уже существующих элементов управления. К примеру, некоторые элементы управления могут скрываться, или сворачиваться, а другие, наоборот, появляться, или разворачиваться. Аналогично, «навигация» может значить, что данные, показываемые в некоторых элементах управления, могут обновляться для отображения текущего состояния приложения. К примеру, при сценарии "master-detail", данные, отображаемые в detail-представлении, обновляются в зависимости от того, какой элемент выбран в master-представлении. Все эти сценарии могут быть расценены, как «навигация», так как пользовательский интерфейс обновляется для отображения внутреннего состояния приложения и того, какую задачу выполняет пользователь в текущий момент.
Навигация в UI может быть как следствием пользовательского взаимодействия, так и реакцией на изменения внутреннего состояния приложения. В некоторых случаях, навигация может порождать совсем небольшие обновления UI, не требующие какой-либо сложной логики. В других случаях, могут быть задействованы сложные бизнес-правила. К примеру, приложение может не позволить пользователю выйти из какой-либо формы, не удостоверившись, что введённые данные корректны.
Реализация навигации в WPF и Silverlight часто может быть довольно прямолинейной, так как обе эти платформы предоставляют встроенную поддержку навигации. Однако реализация навигации может стать довольно сложной, при использовании шаблона MVVM, или в составных приложениях, использующих несколько слабо связанных модулей. Prism предоставляет руководство по реализации навигации в подобных случаях.
Навигация в Prism
Термин «навигация» определён, как процесс, в котором приложение координирует изменения UI в ответ на жесты пользователя, или изменения внутреннего состояния приложения.
Обновления в UI могут быть произведены как с помощью удаления, или добавления элементов управления в визуальное дерево, так и с помощью изменения состояния элементов, уже находящихся в нём. Благодаря гибкости WPF и Silverlight, в них можно применять оба этих подхода. Но на то, какой подход будет более подходящим для вашего случая, может влиять большое количество факторов.
Prism делает различия между двумя типами навигации, описанными выше. Навигация, основанная на изменении состояния уже существующих элементов управления, называется «навигация на основе состояний (state-based navigation)». Навигация, основанная на добавлении, или удалении элементов управления из визуального дерева, называется «навигация на основе представлений (view-based navigation)». Prism предоставляет руководство по реализации этих видов навигации, заостряя внимание на приложениях, использующих шаблон MVVM.
Навигация на основе состояний (State-Based Navigation)
При навигации на основе состояний, представление обновляется как при изменениях состояния модели представлении, так и при взаимодействии пользователя с самим представлением. При этом, вместо того, чтобы заменять представление другим представлением, просто меняется его состояние. В зависимости от того, как меняется состояние представления, это может восприниматься пользователем как навигация.
Этот стиль навигации хорошо подходит в следующих случаях:
- Представлению нужно отобразить те же самые данные или функционал, но в другом виде, или формате.
- Представление должно изменить свою разметку, или стиль, в ответ на изменение состояния модели представления.
- Представление должно произвести модальное, или немодальное взаимодействие с пользователем, без смены контекста представления.
Такой стиль не подходит в тех случаях, когда UI должен предоставить пользователю данные другого типа, или когда пользователь должен переключиться на другую задачу. В таких случаях, лучше всего создать отдельные представления (и модели представления) для представления соответствующих данных и задач, и затем произвести к ним навигацию на основе представлений, что будет описано далее в этой главе. Аналогично, такая навигация не подходит в случаях, когда требуется большое количество изменений состояния пользовательского интерфейса, так как получающиеся представления будут слишком сложные и запутанные. В этом случае, будет более правильным реализовать навигацию на основе представлений, между несколькими представлениями.
Следующие разделы описывает типичные ситуации, в которых может быть использована навигация на основе состояний. Каждый раздел ссылается на State-Based Navigation QuickStart, который представляет собой приложения для обмена мгновенными сообщениями и позволяет пользователю вести переписку и управлять своими контактами.
Отображение данных в различных стилях и форматах
Зачастую, вашему приложению может потребоваться отобразить одну и ту же информацию, но в разных форматах, или стилях. В этом случае, вы можете использоваться навигацию на основе состояний для переключения между различными стилями представления, возможно, с использованием анимации перехода. Для примера, State-Based Navigation QuickStart позволяет пользователю выбрать визуальное представление его контактов — в виде простого текста, или в виде аватарок. Он может выбрать тип представления, щёлкая на кнопках List, или Avatars. Представление делает анимированный переход между этими двумя представлениями, как показано на иллюстрации ниже.
Так как представление оперирует одними и теми же данными, но с разными стилями отображения, то модели представления не требуется выполнять какие-либо действия во время переключения между этими стилями. Такой подход предоставляет большую гибкость дизайнеру пользовательского интерфейса, так как ему не требуется работать с кодом приложения.
Поведения (behaviors) Microsoft Expression Blend облегчают реализацию данного типа навигации в представлении. Приложение State-Based Navigation QuickStart использует Expression Blend's DataStateBehavior
для переключения между визуальными состояниями, определёнными в менеджере визуальных состояний (visual state manager), с помощью радио-кнопок. Одна кнопка включает представлений контактов в виде списка, другая — в виде аватарок.
<DataStateBehavior
Binding="{Binding IsChecked, ElementName= ShowAsListButton}"
TrueState="ShowAsList" FalseState="ShowAsIcons"/>
Когда пользователь нажимает радио-кнопку Contacts, или Avatar, визуальное состояние переключается между ShowAsList
и ShowAsIcons
состоянием. Анимация флип-перехода также определена в менеджере визуальных состояний.
Другой пример использования такого стиля навигации представлен в State-Based Navigation QuickStart, когда пользователь переключается на представление с дополнительной информацией о выбранном контакте, как показано на следующей иллюстрации.
Это также с лёгкостью реализовано с помощью Expression Blend's DataStateBehavior
, однако в данном случае поведение привязано к свойству ShowDetails
модели представления, благодаря которому происходит переключение между визуальными состояниями ShowDetails
и ShowContacts
с использованием анимации флип-перехода.
Отображение состояния приложения
Аналогично, представление в приложении иногда может изменять свою разметку, или стиль, в зависимости от изменения внутреннего состояния приложения, которое, в свою очередь, может быть представлено через свойства модели представления. Пример такого сценария дан в State-Based Navigation QuickStart, где статус подключения клиента предоставлен через свойство ConnectionStatus
в модели представления Chat
. При изменении статуса подключения, представление обновляется (по событию изменения свойства), как представлено на иллюстрации ниже.
Для реализации такого переключения состояний, в представлении объявлено поведение DataStateBehavior
, привязанное к свойству ConnectionStatus
модели представления.
<DataStateBehavior Binding="{Binding ConnectionStatus}"
TrueState="Available" FalseState="Unavailable"/>
Отметьте, что состояние подключения может быть изменено как пользователем через визуальный интерфейс, так и приложением, в зависимости от внутренней логики, или возникновения какого-либо события. Для примера, приложение может перейти в состояние «unavailable», если пользователь не взаимодействует с представление в течение определённого времени, или если календарь пользователя сообщает, что он находится на совещании. State-Based Navigation QuickStart симулирует такое поведение с помощью случайного переключения состояние по таймеру. При смене состояния, обновляется свойство модели представления, после чего представление уведомляется об этом через событие изменения свойства. Пользовательский интерфейс обновляется для отображения изменения состояния подключения.
Все предыдущие примеры включали объявление визуальных состояний в представлении, и переключение между ними в результате пользовательского взаимодействия с представлением, или через изменение значения свойств, объявленных в модели представления. Такой подход позволяет дизайнерам пользовательского интерфейса реализовывать визуальное поведение в стиле навигации без необходимости смены представлений, или изменения какого-либо исходного кода приложения. Этот подход применим, когда представлению требуется отображать одни и те же данные в разных стилях, или с разной разметкой. Он не подходит в ситуациях, когда требуется отобразить данные разных типов, или другую функциональность приложения, а также, когда требуется навигация к другим частям приложения.
Взаимодействие с пользователем
Довольно часто приложению необходимо произвести взаимодействие с пользователем в ограниченной форме. В таких ситуациях бывает проще использовать навигацию на основе состояний в текущем контексте, а не переходить к новому представлению. Для примера, в State-Based Navigation QuickStart пользователь может послать сообщение контакту, нажав на кнопку Send Message. После этого, представление отображает всплывающее сообщение, которое позволяет пользователю ввести желаемое сообщение, как показано ниже. Так как взаимодействие с пользователем ограничено и логически связано с контекстом родительского представления, гораздо проще реализовать его с помощью навигации на основе состояний.
Для достижения такого поведения, State-Based Navigation QuickStart реализует команду SendMessage
, которая привязана к кнопке Send Message. При вызове этой команды, модель представления взаимодействует с представлением для показа всплывающего окна. Это достигается с помощью Interaction Request паттерна, описанного в главе 5, "Реализация паттерна MVVM".
Следующий код показывает, как представление в State-Based Navigation QuickStart использует объект запроса взаимодействия SendMessageRequest
, предоставляемый моделью представления. При возникновении события запроса взаимодействия, представление SendMessageChildWindow
отображается во всплывающем окне.
<prism:InteractionRequestTrigger SourceObject="{Binding SendMessageRequest}">
<prism:PopupChildWindowAction>
<prism:PopupChildWindowAction.ChildWindow>
<vs:SendMessageChildWindow />
</prism:PopupChildWindowAction.ChildWindow>
</prism:PopupChildWindowAction>
</prism:InteractionRequestTrigger>
Продолжение следует.
Автор: Unrul