Нелинейная навигация и петли в Windows Phone 7

Posted on Декабрь 22, 2010

4


Всем добрый вечер!

Не так давно, мы говорили о навигации в Windows Phone 7 и про использование кнопки «Назад». Все правила явно указывают нам на то, что приложение имеет сквозную навигацию с помощью кнопки Назад. Но что же нам делать, если мы не хотим что бы пользователь вышел из приложения при достижении первой страницы? Разработчики Windows Phone 7 запрещают (Формально) убирать основную функцию кнопки назад, но когда это останавливало кого-то из разработчиков?

Итак, возвращаемся к навигации. Нелинейная Навигация (НЛН) может понадобиться Вам, если ваше приложение имеет петлю при навигации. Нет смысла снова изобретать велосипед, тем более что есть команда, которая и занимается разработкой стандартных (или не очень) паттернов для Windows Phone 7, использование которых приветствуется разработчиками платформы.

Приложения в Windows Phone 7 используют страницы как строительные блоки. Большинство приложений построено из нескольких страниц (тип WindowsPhonePage), которые хостятся во фрейме (тип WindowsPhoneFrame) и, как разработчик, Вы можете осуществлять навигацию на новую страницу, а, как пользователь, перемещаться назад и вперед среди существующих. При нажатии кнопки Назад мы проходим по стеку (пусть будет стек-возврата), который, по сути, является историей открытия страниц пользователем (прямо как в браузере). В Текущей версии Windows Phone вы не можете воздействовать на этот стек-возврата и потому нет возможности удалять из него страницы.

Так как разработчики могут вызывать встроенный метод NavigationServices.Navigate что бы передать URI страницы для ее отображения, петли могут стать серьёзной проблемой. Вот, к примеру, если есть краткая обучалка работе с вашим приложением с несколькими страницами. С главной страницы переходим на вторую, дальше на третью, а потом снова на главную.

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

С технической точки зрения, петли это дублирование страниц в вашем стеке-возврата.

Разработчики хотят убрать дубликаты из стека-возврата, чтобы избежать петель. Намного больше о навигации и циклической навигации можно прочитать в Non Linear Navigation документации. Разработчики советуют читать документацию во избежание возникновения петель.

Существует некоторое количество решений проблемы.

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

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

  • Следить за историей навигации для определения потенциальных петель.
  • Как только вы определили потенциальную петлю, начните рекурсивное возвращение подняв флаг «recursive back» и вызывайте NavigationServices.GoBack()
  • Для каждой страницы своего приложения в методе OnNavigatedTo проверять “recursive back”. Если поднят, то идем назад еще раз.

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

NonLinearNavigationService.Instance.Init(RootFrame);

С этого момента спокойно пользуйтесь методом Navigate(), а сервис позаботится обо всем остальном!

Есть несколько ограничений, о которых следует помнить при использовании (НЛН):

  • НЛН не позволит вам создать петлю. Нет никакого способа разрешить петли при использовании НЛН. Если петля — обязательная часть вашего приложения — не используйте НЛН.
  • При использовании Application Bar, вам придется прятать его вручную в методе OnNavigatedFrom что бы избежать неправильного отображения.
  • Что бы избежать бага с кнопкой Назад необходимо использовать следующий код:
 protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
 {
     base.OnBackKeyPress(e);
      if (NavigationService.CanGoBack)
      {
           e.Cancel = true;
           NavigationService.GoBack();
      }
 }
 

Настоятельно рекомендую прочитать документацию к НЛН, что бы лучше понять проблему и ее решение.

Скачать Non-Linear Navigation Service

Реклама