In my Xaml Page I've got a Frame.
I'm trying to have a backButton event to just navigate inside frame .
so I tried to use this piece of code
public MainPage(){
this.InitializeComponent();
if(Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons")) {
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
}
private void HardwareButtons_BackPressed(object sender,BackPressedEventArgs e) {
if(insideFrame.CanGoBack())insideFrame.GoBack();
else Application.Current.Exit();
}
but In phone after doing HardwareButtons_BackPressed event it close the application.
It seems to running some default back button behavior on MainPage...
How can I fix it? And In Windows10 does they add new events to handle back navigation?
[Update]
Now I found out it's better to Use SystemNavigationManager in Windows 10 instead of Input.HardwareButtons.BackPressed.
SystemNavigationManager currentView = SystemNavigationManager.GetForCurrentView();
Windows 10 (UWP) include SystemNavigationManager in Windows.UI.Core namespace for Navigation purpose only.
Because SystemNavigationManager is part of Windows Universal Platform, So, it's supported by all device family running on Windows 10 including Mobile and PC.
For Single Page
If you just want to handle navigation for single page. Follow the following steps
Step 1. Use namespace Windows.UI.Core
using Windows.UI.Core;
Step 2. Register back request event for current view. Best place for this is main constructor of class after InitializeComponent().
public MainPage()
{
this.InitializeComponent();
//register back request event for current view
SystemNavigationManager.GetForCurrentView().BackRequested += MainPage_BackRequested;
}
Step 3. Handle BackRequested event
private void Food_BackRequested(object sender, BackRequestedEventArgs e)
{
if (Frame.CanGoBack)
{
Frame.GoBack();
e.Handled = true;
}
}
For Complete Application at one place for single rootFrame
Best place for handling all backbutton for all Views is App.xaml.cs
Step 1. Use namespace Windows.UI.Core
using Windows.UI.Core;
Step 2. Register back request event for current view. Best place for this is OnLaunched just before Window.Current.Activate
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
...
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
Window.Current.Activate();
}
Step 3. Handle BackRequested event
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
rootFrame.GoBack();
e.Handled = true;
}
}
References- Handle back button pressed in UWP
Hope this is helpful to someone!
You need to tell the system that you handled the backbutton press by setting the Handled property of the BackPressedEventArgs to true.
private void OnHardwareButtonsBackPressed(object sender, BackPressedEventArgs e)
{
// This is the missing line!
e.Handled = true;
// Close the App if you are on the startpage
if (mMainFrame.CurrentSourcePageType == typeof(Startpage))
App.Current.Exit();
// Navigate back
if (mMainFrame.CanGoBack)
{
mMainFrame.GoBack();
}
}
follow these steps:
Add two Global Variables in your page as below.
private NavigationHelper navigationHelper;
private RelayCommand _GoBackCommand;
Then add below code in constructor of specific page.
// below code is to override the back navigation
// hardware back button press event from navigationHelper
_GoBackCommand = new RelayCommand
(
() => this.CheckGoBack(),
() => this.CanCheckGoBack()
);
navigationHelper.GoBackCommand = _GoBackCommand;
// ---------
Then add both those methods we've just declared in constructor.
private bool CanCheckGoBack()
{
// this should be always true to make sure the app handles back buton manually.
return true;
}
private void CheckGoBack()
{
// this will be execute when back button will be pressed
}
ps. - for this you might need to use BasicPage instead of BlankPage while adding new page.
hope this will help..!
Try this.It will work for frame back navigation.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (Frame.CanGoBack)
{
e.Handled = true;
Frame.GoBack();
}
}
}
I think this is because you add HardwareButtons_BackPressed in your page instead on in app.xaml.cs.
In app.xaml.cs :
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame != null && rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
Now, back button of your phone will work on any pages.
And then, if you want to add a particular button doing back in any page :
In the particular page (or each pages if you want) :
public void btn_return_Tapped(object sender, TappedRoutedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame != null && rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
Source :
http://windowsapptutorials.com/tips/general-tips/handling-the-back-button-in-a-windows-phone-8-1-app/
Related
I have a UWP app - the design has a "Back" button in the screen content, which I would like to use to trigger the system navigation event handled in my App.xaml.cs file. My current click handler, which is pasted to each file which needs it is:
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
rootFrame.GoBack();
How would I instead trigger the back event, which would trigger the back event handler which already contains this code?
In App.xaml.cs, add this to OnLaunced(...):
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
...
if (rootFrame == null)
{
...
// Register a handler for BackRequested events
SystemNavigationManager.GetForCurrentView().BackRequested += this.OnBackRequested;
}
...
}
Where in OnBackRequested(...), which can also be in App.xaml.cs:
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
This could easily be adapted to support multiple frames if you implement any custom navigation, and you can also add global handling of showing/hiding the back button via something like:
public void UpdateBackButton(Frane frame)
{
bool canGoBack = (frame?.CanGoBack ?? false);
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = canGoBack
? AppViewBackButtonVisibility.Visible
: AppViewBackButtonVisibility.Collapsed;
}
You can programmatically call back via a function like this in App.xaml.cs or in a custom navigation manager:
public bool TryGoBack(Frame frame)
{
bool handled = false;
if (frame?.CanGoBack ?? false)
{
handled = true;
frame.GoBack();
}
this.UpdateBackButton(frame);
return handled;
}
How would I handle the back button for windows mobile 10 and the back button for windows 10 tablet mode? I've been looking everywhere but can't find any examples for it.
This topic is one of the examples used in the Guide to Universal Windows Platform apps . I strongly suggest reading that when getting started with Universal apps.
For the button on the page header use Windows.UI.Core.SystemNavigationManager and set the AppViewBackButtonVisibility property to show or hide the button and handle the BackRequested event to perform the navigation.
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += (s,a) =>
{
Debug.WriteLine("BackRequested");
if (Frame.CanGoBack)
{
Frame.GoBack();
a.Handled = true;
}
}
You wire up the hardware back button the same as you do in Windows Phone 8.1, but you should check for the PhoneContract (or the individual class and method) to make sure it is there:
if (ApiInformation.IsApiContractPresent ("Windows.Phone.PhoneContract", 1, 0)) {
Windows.Phone.UI.Input.HardwareButtons.BackPressed += (s, a) =>
{
Debug.WriteLine("BackPressed");
if (Frame.CanGoBack)
{
Frame.GoBack();
a.Handled = true;
}
};
}
Add the following code to your App.xaml.cs and it will handle the navigation on desktop, tablet and mobile (I tested it on the mobile emulator)
for better highlighted differences and explanation (Handling The Back Button In Windows 10 UWP Apps by JEFF PROSISE)
sealed partial class App : Application
{
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
rootFrame.Navigated += OnNavigated;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
// TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
// Register a handler for BackRequested events and set the
// visibility of the Back button
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
rootFrame.CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
}
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
private void OnNavigated(object sender, NavigationEventArgs e)
{
// Each time a navigation event occurs, update the Back button's visibility
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
((Frame)sender).CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
// TODO: Save application state and stop any background activity
deferral.Complete();
}
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
}
In my windows phone app sometimes it takes me two page backward although I pressed hardware back button just once.
To handle the back button I used following code snippet:
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
if (Frame.CanGoBack)
Frame.GoBack();
}
And in OnNavigatedTo() method I added following line:
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
How can I make sure that one back button press will take just one page backward?
Add following line into the OnNavigatedFrom method:
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
In case the OnNavifatedFrom doesn't exist in your partial class of the XAML page, create it like bellow:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
}
I have two pages in my app.One is blankPage and other is basic page. On basic page I want to provide a message if a user press back button like
"Are you sure you want to quit" .If Yes then go back else remain there , this working fine by using this code
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
private async void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
MessageDialog dlg = new MessageDialog("Are you sure you want to quit you will loose all your work ?", "Warning");
dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(CommandHandler1)));
dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler(CommandHandler1)));
await dlg.ShowAsync();
}
private void CommandHandler1(IUICommand command)
{
var label = command.Label;
switch (label)
{
case "Yes":
{
this.Frame.Navigate(typeof(MainPage));
break;
}
case "No":
{
break;
}
}
}
But when I am pressing back button on my BlankPage this message also appears there and also appearing in all other basic page if I add more . What mistake am I doing??
You are registering hardware back button in page constructor or page load event and once this event is registered you are not unregistering this event. BackPress is app level. for correctly using this event on your desired page register Back Press event in your OnNavigatedTo override method and unregister this event in OnNavigatedFrom ovrride metho. here is how.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
}
I have a popup window in my windows phone 8.1 runtime application.
While back button pressed and popup is opened in a page, the app should stay in the page itself, else it should go back. This is my concept. So, I coded like below:
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
if (PopupWindow.IsOpen)
{
PopupWindow.IsOpen = false;
e.Handled = true;
}
}
Even if the popup windows is open in the page, the app goes to the previous page. I used the same logic in windows phone silverlight application and that worked.
NOTE: I'm using Basic Page.
What mistake actually I'm doing ?
Check two things:
by default in NavigationHelper, HardwareButtons_BackPressed lacks checking if the event was already handeled, try to improve it:
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
// if (this.GoBackCommand.CanExecute(null)) // this is as a default
if (this.GoBackCommand.CanExecute(null) && !e.Handled) // add a check-up
// ... rest of the code
look at your App.xaml.cs file, and in App() there is HardwareButtons_BackPressed subscribed (check if subscribed method also navigates back):
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
// HardwareButtons.BackPressed += HardwareButtons_BackPressed; // this line also could fire Frame.GoBack() (as default project template)
// of course check what is in the above method
}
Also remeber that events are fired in the order you have subscribed them and for example Navigation helper subscribes in Loaded event. If you subscribe after then the navigation will be first. You may subscribe before or maybe use a flag.
I resolve in thi way
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
protected virtual void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
e.Handled = true;
}