Статьи

31 день Windows 8 | День № 13 Навигация


Эта статья является Днем № 13 из серии под названием
31 Дней Windows 8 . Каждая из статей этой серии будет опубликована как для
HTML5 / JS, так и для
XAML / C # . Вы можете найти дополнительные ресурсы, загрузки и исходный код на нашем
сайте .

advertisementsample4

Последние несколько дней мы потратили на то, чтобы обновить систему, предоставив информацию, позволяющую пользователю узнать, что происходит. Фактически, в первые 12 дней этой серии мы потратили очень мало времени на обсуждение того, как выполнить одно из самых распространенных действий, с которыми мы сталкиваемся при разработке Windows 8: переход между страницами XAML.

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

  • Простой процесс перехода со страницы А на страницу Б. Что происходит, когда и какая информация нам доступна?
  • Передача данных с одной страницы на другую. Это не только строки и целые числа, мы также можем передавать целые объекты между страницами.
  • Кеширование страниц. Когда пользователь нажимает кнопку «Назад», он не хочет обнаружить, что все введенные им данные исчезли. Мы обсудим это позже.

Навигация между страницами в Windows 8 XAML

Кажется, что каждый раз, когда мы сталкиваемся с новой платформой, появляется также новый способ навигации между страницами в приложении XAML. Windows 8 ничем не отличается в этом отношении. Этот процесс легко объяснить, если вы проведете вас через создание некоторых страниц, поэтому давайте начнем с этого.

Создайте новый пустой шаблон приложения, а затем добавьте в него два новых элемента базовой страницы. Для этого примера вы можете назвать их PageA.xaml и PageB.xaml.

13-XAML-BasicPage

На каждой из этих страниц есть строка XAML, которая устанавливает AppName.

<Page.Resources>

    <x:String x:Key="AppName">My Application</x:String>

</Page.Resources>

Обычно мы переносим это в наш файл App.xaml и позволяем применять его ко всем страницам в нашем приложении. На сегодняшний день мы собираемся использовать этот простой механизм, чтобы дать каждой из наших страниц отличное имя, которое мы можем видеть при загрузке. Установите значение AppName PageA.xaml равным «Page A», а AppName PageB.xaml равным «Page B», чтобы ваши страницы выглядели так:

13-XAML-страница A13-XAML-Страница B

Чтобы сделать ваш образец простым в использовании, мы также сделаем быстрое изменение в нашем файле App.xaml.cs. В нижней части метода OnLaunched () в App.xaml.cs находится некоторый код, который выглядит следующим образом:

if (rootFrame.Content == null)

{

    if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))

    {

        throw new Exception("Failed to create initial page");

    }

}

Вы захотите изменить ссылку с typeof (MainPage) на typeof (PageA). Как это:

if (rootFrame.Content == null)

{

    if (!rootFrame.Navigate(typeof(PageA), args.Arguments))

    {

        throw new Exception("Failed to create initial page");

    }

}

Это приведет к запуску вашего приложения с начальной страницей PageA.xaml. На данный момент, вперед и запустить свой проект. Вы должны увидеть, что он начинается с заставки , а затем должна загрузиться PageA. Вы также должны заметить, что, хотя наш предварительный просмотр в Visual Studio 2012 показывает значок стрелки рядом с заголовком нашей страницы, он зависит от того, способна ли страница «вернуться» со свойством Frame.CanGoBack. Мы поговорим об этом чуть позже.

А пока давайте перейдем к навигации. Технически вы уже видели это в нашем файле App.xaml.cs, но это выглядит немного иначе, когда вы просто переходите от страницы к странице. Я добавил элемент управления <Button> в свой файл PageA.xaml, прямо перед разделом <VisualStateManager>. XAML для этого выглядит так:

<Button x:Name="PageBButton"

        Grid.Row="1"

        Content="To Page B"

        Width="150"

        Height="150"

        Click="PageBButton_Click" />

В обработчике событий для этого <Button> мы пишем наш первый оператор навигации (наконец-то!)

private void PageBButton_Click(object sender, RoutedEventArgs e)

{

    Frame.Navigate(typeof(PageB));

}

Как видите, это довольно простой процесс. Итак, давайте сделаем это немного сложнее, добавив кнопку навигации на страницу B. Это может показатьсякак повторяющееся, простое задание, но вы обнаружите, что у нас могут возникнуть проблемы довольно быстро. (Вы должны запустить свой проект в этот момент, чтобы убедиться, что вы действительно переходите к файлу страницы B.) Добавьте тот же тип <Button> и обработчик события в PageB, но, очевидно, на этот раз укажите на PageA. Теперь у вас есть кнопка на каждой странице, которая указывает на другую. Если вы используете только эти кнопки для навигации, вы в конечном итоге создаете ОГРОМНЫЙ стек навигации назад, и это делает любую концепцию кнопки Назад совершенно неактуальной. В этом случае нам нужно реализовать обработчик события GoHome, который является частью объекта LayoutAwarePage, который мы используем. Чтобы эффективно проиллюстрировать этот пример, добавьте в свой PageB.xaml вторую кнопку с сопровождающим новым обработчиком событий. В этом обработчике событий, однако,мы не собираемся переходить на страницу. Вместо этого мы собираемся создать событие GoHome и вызвать его. Вот как это выглядит:

protected override void GoHome(object sender, RoutedEventArgs e)

{

    if (this.Frame != null)

    {

        while (this.Frame.CanGoBack) this.Frame.GoBack();

    }

}

 

private void HomeButton_Click(object sender, RoutedEventArgs e)

{

    base.GoHome(sender, e);

}

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

Передача данных между страницами XAML в Windows 8

Далее мы хотим передать данные между нашими страницами. Может быть, объект, может быть строка, но, тем не менее, данные. Оказывается, наш метод Frame.Navigate () перегружен, чтобы также принять параметр данных. Для этого примера я добавил TextBox и Button на свою PageA, но на этом этапе я предполагаю, что вы знаете, как это сделать. Важной частью этого является то, где у меня есть обработчик событий, который извлекает текстовое значение из TextBox и отправляет его как часть метода Navigate (). Как это:

private void GoButton_Click(object sender, RoutedEventArgs e)

{

    Frame.Navigate(typeof(PageB), TextBoxValue.Text);

}

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

protected override void OnNavigatedTo(NavigationEventArgs e)

{

    base.OnNavigatedTo(e);

 

    string text = e.Parameter as string;

 

    if (!string.IsNullOrWhiteSpace(text))

    {

        TextBlockValue.Text = text;

    }

    else

    {

        TextBlockValue.Text = "You need to pass a string. Press back and enter a value.";

    }

}

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

Кроме того, я упоминал ранее, что вы также можете отправлять завершенные объекты, используя этот механизм. Помните наш класс Element еще в День № 4 ? Я собираюсь передать пользовательский объект Element из PageA в PageB в следующем примере. Вот код PageA:

private void Gallium_Click(object sender, RoutedEventArgs e)

{

    Frame.Navigate(typeof(PageB), new Element { AtomicNumber = 31,

                                                AtomicWeight = 69.72,

                                                Category = "Other Metals",

                                                Name = "Gallium",

                                                Symbol = "Ga",

                                                State = "Solid" });

}

Вы можете ясно видеть, что мы передаем совершенно новый объект Element в PageB. Вот PageB ловит эти данные:

protected override void OnNavigatedTo(NavigationEventArgs e)

{

    base.OnNavigatedTo(e);

 

    Element gallium = e.Parameter as Element;

    TextBlockValue.Text = gallium.Category;

}

Передача данных между страницами XAML в Windows 8

Последнее, что мы хотим рассмотреть в связи с навигацией, — это кэширование страниц. В этом последнем примере я использую наш пример приложения в состоянии, когда я передавал строковые значения туда и обратно. Возможно, вы заметили, что если вы создали свое собственное приложение-образец, то, если вы наберете что-то в TextBox на PageA и отправите эти данные в PageB, когда вы нажмете кнопку «Назад», чтобы вернуться к PageA, она не запомнит, что вы ввели. в коробке. Это невероятно расстраивающий шаблон пользовательского опыта, который вы постоянно видите в сети.

Мы можем избежать этого с помощью одной простой строки в конструкторе страниц, которые мы хотим кешировать:

public PageA()

{

    this.InitializeComponent();

    NavigationCacheMode = NavigationCacheMode.Enabled;

}

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

Резюме

Это был обширный обзор навигации в приложениях XAML для Windows 8. Мы рассмотрели перемещение между страницами, передачу данных между страницами и кэширование этих страниц, когда пользователь нажимает кнопку «Назад».

Если вы хотите загрузить полный пример кода из этой статьи, вы можете щелкнуть значок ниже. (Обратите внимание, что кнопка Gallium в настоящее время отключена, вам нужно раскомментировать обработчик события для этой кнопки, а также код в PageB.xaml.cs, чтобы это работало. PageB может принимать только один тип параметра в время, и в настоящее время он настроен на строку.)

downloadXAML

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

downloadTheTools