Статьи

EvenTiles от начала до конца — часть 8

В предыдущем выпуске этой серии о том, как разработать приложение для Windows Phone с нуля, мы говорили о быстрой смене приложений и Tombstoning. Мы увидели, как Visual Studio 2010 может помочь нам в тестировании сценариев Tombstoning. Мы также рассмотрели, как сохранить данные приложения, когда приложение прерывается другими приложениями, и как восстановить эти данные при возврате на передний план.

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

Пользователь вводит данные в текстовое поле внутри страницы настроек. Это означает, что клавиатура видна, а текстовое поле имеет фокус ввода и мигающий курсор в месте ввода данных. Иногда в середине ввода текста пользователь нажимает кнопку «Пуск», чтобы активировать другое приложение, чтобы вернуться к нашему приложению только через некоторое время. Несмотря на то, что мы сохранили все данные, введенные пользователем (поскольку мы сохраняем содержимое текстового поля при переходе от страницы настроек), текстовое поле не имеет фокуса, когда пользователь возвращается на страницу настроек, а также курсор, расположенный справа место нахождения. Чтобы восстановить точно такую ​​же ситуацию, нам нужно сохранить дополнительные данные при переходе от страницы настроек. Это приводит к другой проблеме.Чтобы сохранить состояние локальной страницы при переходе от страницы настроек, мы можем использовать следующий код:

Сохранение состояния страницы:

    protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
        if (!e.IsNavigationInitiator)
        {
            TextBox tb = FocusManager.GetFocusedElement() as TextBox;
     
            if (tb != null)
            {
                this.State[keySelectionLength] = tb.SelectionLength;
                this.State[keySelectionStart] = tb.SelectionStart;
            }
        }
        App.ActualSecBackContent = tbBackContent.Text;
        base.OnNavigatedFrom(e);
    }

Каждый раз, когда вызывается OnNavigatedFrom, существует вероятность того, что приложение перемещается в фоновый режим. Если это так, свойство IsNavigationInitiator имеет значение false . Если приложение перемещается в фоновый режим, мы проверяем, имеет ли текстовое поле фокус. Если это так, мы будем хранить местоположение курсора, добавляя записи как для SelectionStart (местоположение, где находится курсор), так и для SelectionLength. Если, с другой стороны, текстовое поле не имеет фокуса, нам не нужно хранить информацию о состоянии страницы, только свойство Text текстового поля.

Получить информацию о состоянии страницы обратно можно в методе OnNavigatedTo следующим образом:

Восстановить состояние страницы:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        tbBackContent.Text = App.ActualSecBackContent;
        btnRestore.Visibility = tbBackContent.Text.Equals(App.DefaultSecBackContent) ?
            System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
     
        if (this.State.ContainsKey(keySelectionLength))
        {
            tbBackContent.SelectionLength = (int)this.State[keySelectionLength];
            tbBackContent.SelectionStart = (int)this.State[keySelectionStart];
            focusToTextBox = true;
        }
        base.OnNavigatedTo(e);
    }

Однако невозможно вернуть фокус обратно элементу управления textbox в методе OnNavigatedTo , поскольку при вызове OnNavigatedTo различные элементы пользовательского интерфейса еще не инициализированы . По этой причине для булевой переменной устанавливается значение true и фактически задается фокус текстового поля при запуске события Loaded на странице. Если приложение возвращается из фона, а focusToTextBox имеет значение true, текстовое поле tbBackContent получит фокус:

Восстановить фокус ввода текстового поля:

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (focusToTextBox)
        {
            tbBackContent.Focus();
        }
    }

Если приложение всегда будет захоронено, этого будет достаточно для сохранения / восстановления информации о состоянии страницы и восстановления фокуса ввода, если текстовое поле имело фокус, когда приложение было помещено в фоновый режим. Однако с Windows Phone Mango приложения могут извлечь выгоду из неактивного состояния, когда они остаются в памяти, даже находясь в фоновом режиме. На самом деле не существует четкого различия с точки зрения разработчика между Dormant и Tombstoned, за исключением того факта, что в случае возврата из Tombstoned выполняется конструктор страницы, а это не тот случай, когда приложение возвращается из Dormant, поскольку приложение было еще в памяти. Как следствие, возврат из неактивного состояния также означает, что событие Loaded на странице не запускается. Так,хотя возвращение на передний план происходит быстрее, если бы мы находились в состоянии бездействия, в этом случае нам нужна дополнительная логика, чтобы сосредоточить внимание на текстовом поле. Чтобы различать Dormant и Tombstoned, можно установить для логической переменной в конструкторе страницы значение true и проверить эту переменную в методе OnNavigatedTo:

Дремлющий против надгробной плиты:

    private bool focusToTextBox;
    private bool pageConstructed;
     
    public SettingsPage()
    {
        InitializeComponent();
        pageConstructed = true;
    }

Значение переменной pageConstructed определяет, возвращаемся ли мы из неактивного состояния на передний план (false) или нет. Если мы не возвращаемся из неактивного состояния, нам нужно определить в OnNavigatedTo, вернулись ли мы из состояния Tombstoned, чтобы дополнительно установить фокус на текстовое поле. Однако, если мы возвращаемся из неактивной ситуации, сам метод OnNavigatedTo должен использоваться для установки фокуса на текстовое поле, если это необходимо. Модифицированный метод OnNavigatedTo выглядит следующим образом:

Полная реконструкция страницы:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        tbBackContent.Text = App.ActualSecBackContent;
        btnRestore.Visibility = tbBackContent.Text.Equals(App.DefaultSecBackContent) ?
            System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
     
        if (this.State.ContainsKey(keySelectionLength))
        {
            tbBackContent.SelectionLength = (int)this.State[keySelectionLength];
            tbBackContent.SelectionStart = (int)this.State[keySelectionStart];
            if (!pageConstructed)
            {
                tbBackContent.Focus();
            }
            else
            {
                focusToTextBox = true;
            }
        }
        base.OnNavigatedTo(e);
    }

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

Обновление после создания видео. Несмотря на то, что в видео кажется, что приложение работает должным образом как при возвращении из состояния бездействия, так и из состояний захоронения, это не совсем так. Несмотря на то, что фокус текстового поля восстанавливается должным образом при необходимости, текстовый блок также получает фокус каждый раз, когда мы возвращаемся из фона, за исключением первого раза. Причина этого заключается в том, что словарные записи в коллекции Page.State не были удалены после использования в методе OnNavigatedTo. Исходный код EvenTiles содержит исправление для этой недокументированной функции приложения .

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

Скачать исходный код EvenTiles Episode 8

После загрузки и разархивирования примера кода вы можете открыть решение EvenTiles в Visual Studio 2010 Express для Windows Phone. Для этого в вашей системе разработки должен быть установлен Windows Phone SDK 7.1 . Если у вас есть телефон, разблокированный разработчиком, вы можете развернуть приложение на своем телефоне, если у вас нет телефона, разблокированного разработчиком, вы все равно можете поэкспериментировать с этим приложением внутри эмулятора.

В следующем эпизоде ​​EvenTiles мы, наконец, дойдем до сердца и души приложения, когда собираемся создать Secondary Tile.


Источник: http://mstruys.com/2011/12/14/eventiles-from-start-to-finishpart-8/