Windows 10 UAP back button - c#

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();
}
}
}

Related

UWP on screen back button - how to trigger system back event?

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

UWP - MessageDialog crashes the app on Windows Phone and tablet mode

In a Windows 10 Universal app, I want to display a MessageDialog when the back button is pressed.
The code of my page is the following :
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
SystemNavigationManager.GetForCurrentView().BackRequested += GamePage_BackRequested;
}
private async void GamePage_BackRequested(object sender, BackRequestedEventArgs e)
{
var dialog = new Windows.UI.Popups.MessageDialog("Are you sure ?");
dialog.Commands.Add(new Windows.UI.Popups.UICommand("Yes"));
dialog.Commands.Add(new Windows.UI.Popups.UICommand("No"));
var result = await dialog.ShowAsync();
}
When I lauch the App in "local machine", the dialog is well displayed. But when I turn Windows to "tablet mode", or when i try it on my Windows Phone, the ShowAsync method crashes the App (with no error).
Why is the app crashing ?
The problem seems to be that the "dialog.ShowAsync()" method should be called from the UI thread.
This is how I solved it :
private void GamePage_BackRequested(object sender, BackRequestedEventArgs e)
{
e.Handled = true;
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
var d = dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ShowConfirmationDialog(rootFrame));
}
}
public async void ShowConfirmationDialog(Frame rootFrame)
{
var dialog = new Windows.UI.Popups.MessageDialog("Are you sure ?");
dialog.Commands.Add(new Windows.UI.Popups.UICommand("Yes") { Id = 0 });
dialog.Commands.Add(new Windows.UI.Popups.UICommand("No") { Id = 1 });
var result = await dialog.ShowAsync();
if (result != null && result.Label == "Yes")
{
rootFrame.GoBack();
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;
SystemNavigationManager.GetForCurrentView().BackRequested += GamePage_BackRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager.GetForCurrentView().BackRequested -= GamePage_BackRequested;
}
You should handle the backrequest ; e.handled = true;
private async void GamePage_BackRequested(object sender, BackRequestedEventArgs e)
{
e.handled = true;
var dialog = new Windows.UI.Popups.MessageDialog("Are you sure ?");
dialog.Commands.Add(new Windows.UI.Popups.UICommand("Yes"));
dialog.Commands.Add(new Windows.UI.Popups.UICommand("No"));
var result = await dialog.ShowAsync();
}
You should add onnavigatedfrom method to unregister the event, otherwise it will trigger twice !
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
if (gb.DetectPlatform() == Platform.WindowsPhone)
HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
elde
SystemNavigationManager.GetForCurrentView().BackRequested -= GamePage_BackRequested;
};
}
There is no way to accomplish what you want -- the back key handler requires an immediate answer (handled or not) but the dialog is inherently async.
You can of course choose to mark the event as Handled before you show the dialog, but then if the user says "Yes" there's no way you can then navigate away. You can of course terminate the app, but that's a bad idea (see final paragraph)
That said, you don't typically need this dialog because in Windows 10, backing out of an app doesn't terminate it, it just switches to the previous app (or the Start menu). The user can trivially return to it via the task switcher (or launching it again).
My UWP application was crashing when I called MessageDialog.ShowAsync in the Application.UnhandledException event handler and this was the top result when I searched for an answer.
I resolved the issue by setting UnhandledExceptionEventArgs.Handled = true before calling MessageDialog.ShowAsync.
This is well documented in another SO question, but I didn't find that answer until after I figured out the solution because I didn't realize calling the method from Application.UnhandledException was significant.

Handling Back Navigation Windows 10 (UWP)

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/

Navigate to Button Click Event in Lens Application for Windows Phone 8

Upon pressing the Lens tile icon for my application within the default camera application on Windows Phone, I would like to navigate to my application. I have this working, although I am using the CameraCaptureTask to take photos and then I save and display them within my MainPage. I am calling CameraCaptureTask on a click event, so my question is how might I access this click event when I select the Application Tile in the Lens picker?
App.xaml.cs
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
//RootFrame = new PhoneApplicationFrame();
RootFrame = new TransitionFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Assign the lens example URI-mapper class to the application frame.
RootFrame.UriMapper = new LensUriMapper();
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Handle reset requests for clearing the backstack
RootFrame.Navigated += CheckForResetNavigation;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
LensUriMapper.cs
class LensUriMapper : UriMapperBase
{
private string tempUri;
public override Uri MapUri(Uri uri)
{
tempUri = uri.ToString();
// Look for a URI from the lens picker.
if (tempUri.Contains("ViewfinderLaunch"))
{
// Launch as a lens, launch viewfinder screen.
//return new Uri("/Views/MainPage.xaml", UriKind.Relative);
return new Uri("/Views/MainPage.xaml?Viewfinder=1", UriKind.Relative);
}
}
// Otherwise perform normal launch.
return uri;
}
}
MainPage.xaml.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("Viewfinder"))
{
newButton_Click(null, null);
}
}
void newButton_Click(object sender, EventArgs e)
{
_cameraTask.Show();
}
In addition, how might I navigate directly back to the default camera application upon the back key press as stated in MSDN's Lens application guidelines?
you can add a parameter to the ViewfinderLaunch uri:
return new Uri("/Views/MainPage.xaml?Viewfinder=1", UriKind.Relative);
Next you have to override the "OnNavigatedTo" method of your MainPage to check if Viewfinder parameter is setted:
if (NavigationContext.QueryString.ContainsKey("Viewfinder"))
{
newButton_Click(null, null);
}

How to store Application state in windows phone

I have an Application which works totally fine when I open it once, but now the problem is if the user hits windows home key it exits the application and move my app to background. Now if the user long press back key and open my application it returns to the same page from which the user hit the home key. But if the user clicks on application icon, my app starts from the beginning which I don't want. Please help me. Thanks
Tell me where should I put code so that I get the desired result.
My App.xaml is below:
=================
namespace MyProj
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
// Easy access to the root frame
public PhoneApplicationFrame RootFrame
{
get;
private set;
}
// Constructor
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Disable the application idle detection by setting the UserIdleDetectionMode property of the
// application's PhoneApplicationService object to Disabled.
// Caution:- Use this under debug mode only. Application that disable user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
}
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
// Restart session
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
ViewModelLocator.Cleanup();
}
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
#region Phone application initialization
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
//RootFrame = new PhoneApplicationFrame();
RootFrame = new TransitionFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
#endregion
}
}
You need to implement tombstone functionality. Just read
App activation and deactivation for Windows Phone

Categories