Frage

My question is how to define own action for given page i.e. first click on back button close popup and second navigates from page?

Since WP8.1 NavigationHelper is quite useful yet it only gives one general action for clicking back key (exiting page).

I can't overwrite NavigationHelper since it gives no setters for its commands and handler for back button click is private, so I can't unpin it on entering page. Making changes in NavigationHelper seems ugly since I'm developing universal app for W8.1 & WP8.1 and I have multiple pages that require custom handler for back button.

--edit--

Commands allows overwriting, yet I'll use original command on each page. Solution is to create new command on each page?

War es hilfreich?

Lösung

I think you can subscribe to Windows.Phone.UI.Input.HardwareButtons.BackPressed before the NavigationHelper does (as I've checked it subscribes in Page.Loaded event). In fact for this purpose (as you will be adding EventHandlers later) you will need a special InvokingMethod that will invoke your EventHandlers:

// 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
    }
}

In this case BackPressed will be fired before NavigationHelper's eventhandler and if you set e.Handeled = true; then you should stay on the same Page.

Note also that instead of modifying App.xaml.cs you can extend this way your Page class or NavigationHelper, it depends on your needs.

Andere Tipps

Depending on the order the events are added is pretty ugly. It'd be much cleaner to work with the NavigationHelper than to try to bypass it.

You can set your own RelayCommand to the NavigationHelper's GoBackCommand and GoForewardCommand properties. Another option would be to subclass NavigationHelper and override the CanGoBack and GoBack functions (they're virtual).

Either way you can replace the NavigationHelper's default action with your custom logic to close any intermediate states or call Frame.GoBack as appropriate.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top