Действие на странице для кнопки «Назад»

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

Поскольку WP8.1 NavigationHelper весьма полезен, он дает только одно общее действие для нажатия клавиши «Назад» (выход со страницы).

Я не могу перезаписать NavigationHelper, поскольку он не дает сеттеров для своих команд, а обработчик нажатия кнопки «Назад» является закрытым, поэтому я не могу открепить его при входе на страницу. Внесение изменений в NavigationHelper кажется уродливым, поскольку я разрабатываю универсальное приложение для W8.1 и WP8.1, и у меня есть несколько страниц, для которых требуется собственный обработчик для кнопки «Назад».

--редактировать--

Команды позволяют перезаписывать, но я буду использовать исходную команду на каждой странице. Решение состоит в том, чтобы создать новую команду на каждой странице?


person Tadeusz    schedule 29.04.2014    source источник


Ответы (2)


Я думаю, вы можете подписаться на Windows.Phone.UI.Input.HardwareButtons.BackPressed до того, как это сделает NavigationHelper (как я проверил, он подписывается в событии Page.Loaded). На самом деле для этой цели (поскольку вы будете добавлять обработчики событий позже) вам понадобится специальный InvokingMethod, который будет вызывать ваши обработчики событий:

// in App.xaml.cs make a method and a listOfHandlers:
private List<EventHandler<BackPressedEventArgs>> listOfHandlers = new List<EventHandler<BackPressedEventArgs>>();

private void InvokingMethod(object sender, BackPressedEventArgs e)
{
   for (int i = 0; i < listOfHandlers.Count; i++)
       listOfHandlers[i](sender, e);
}

public event EventHandler<BackPressedEventArgs> myBackKeyEvent
{
   add { listOfHandlers.Add(value); }
   remove { listOfHandlers.Remove(value); }
}

// look that as it is a collection you can make a variety of things with it
// for example provide a method that will put your new event on top of it
// it will beinvoked as first
public void AddToTop(EventHandler<BackPressedEventArgs> eventToAdd) { listOfHandlers.Insert(0, eventToAdd); }

// in App constructor: - do this as FIRST eventhandler subscribed!
HardwareButtons.BackPressed += InvokingMethod;

// subscription:
(App.Current as App).myBackKeyEvent += MyClosingPopupHandler;
// or
(App.Current as App).AddToTop(MyClosingPopupHandler); // it should be fired first

// also you will need to change in NavigationHelper.cs behaviour of HardwereButtons_BackPressed
// so that it won't fire while e.Handeled == true
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
    if (!e.Handled)
    {
        // rest of the code
    }
}

В этом случае BackPressed будет запущен перед обработчиком событий NavigationHelper, и если вы установите e.Handeled = true;, вы должны остаться на той же странице.

Также обратите внимание, что вместо изменения App.xaml.cs вы можете расширить таким образом свой класс Page или NavigationHelper, это зависит от ваших потребностей.

person Romasz    schedule 29.04.2014

В зависимости от порядка добавления событий довольно уродливо. Было бы намного чище работать с NavigationHelper, чем пытаться обойти его.

Вы можете установить свой собственный RelayCommand для свойств GoBackCommand и GoForewardCommand NavigationHelper. Другой вариант — создать подкласс NavigationHelper и переопределить функции CanGoBack и GoBack (они виртуальные).

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

person Rob Caplan - MSFT    schedule 19.11.2014
comment
+1 Правильно, гораздо более чистое решение - ссылка на ответ с примером - person Romasz; 19.11.2014