I want to know if user opened app by clicking SecondaryTile (and also which one was clicked).
Now I have OnNavigatedTo method:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
if (!String.IsNullOrEmpty(e.Parameter.ToString()))
{
//e.Parameter is not null, LiveTile was used
//do something
}
else
{
//No of SecondaryTiles were clicked
}
}
This of course works, but only if app was previously closed. But when app was previously opened, runs in background and user click on LiveTile, then app is being shown but this method is not executed.
How can I handle this scenario?
MSDN: Override the OnLaunched method to perform any general app initialization that should occur only when the user launches your app normally (for example, by tapping the app tile).
You should override or update the OnLaunched event to track app activation moment and analyze corresponding arguments (app.xaml.cs file).
In short, if you look on how OnNavigatedTo event is rised -- it comes from the OnLaunched event that checks whether rootFrame's content already exists or not:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
...
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);
}
...
}
As you may imagine in your scenario it is not true, so navigation event never happens.
Related
This is a simple question, but I still could not Google for a solution. What event in a C# UWP app runs only once per page navigation.
I added an event handler for back navigation right after:
this.InitializeComponent();
in the page constructor.
If I go back and forth the first and second page twice, it throws an error and debugging found that the event to handle back navigation was called twice, since the code in the page constructor also ran twice.
So in which event can I write code that I only want to run only once per page navigation. Or is there something similar to the below from ASP.net?
if (!Page.isPostback) {
//do something
}
There is a virtual method you can override on the page class: OnNavigatedTo which will be called by the framework when the page is finished loading and becomes the source of the parent frame.
https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.page.onnavigatedto#Windows_UI_Xaml_Controls_Page_OnNavigatedTo_Windows_UI_Xaml_Navigation_NavigationEventArgs_
Although I accepted another answer, in my specific situation the following code is better, cause it checks whether the back button handler is set or not.
private void App_BackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
return;
// If we can go back and the event has not already been handled, do so.
if (rootFrame.CanGoBack && e.Handled == false)
{
e.Handled = true;
rootFrame.GoBack();
}
}
So, as per the docs I attach a handler when I navigate to a page:
protected override void OnNavigatedTo(NavigationEventArgs e) {
/* Attach back listener to handle the back press */
SystemNavigationManager.GetForCurrentView().BackRequested += NavigationPage_BackRequested;
...
}
And I detach it when leaving:
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) {
SystemNavigationManager.GetForCurrentView().BackRequested -= NavigationPage_BackRequested;
e.Cancel = false;
}
And I mark the event as handled to prevent the system from handling it:
private void NavigationPage_BackRequested(object sender, BackRequestedEventArgs e) {
e.Handled = true;
}
But the system still handles the back click and I get navigated away. Why?
Your code shown above is working fine (tested on my machine), but the big question is: do you try to cancel a system provided navigation event or a Frame.GoBack() event implemented by the software button of your application?
SystemNavigationManager: Provides a way for an app to respond to system provided back-navigation events.
If you look at the backwards navigation documentation, only certain back buttons (hardware/software) are system provided events, e.g. the software button at the bottom in Tablet mode.
However quite a few project templates (in Visual Studio or from MVVM libraries) also provide a software back button (quite often at the top left) and wire this event to the Frame.GoBack() method. This is NOT a system provided event and can't be cancelled this way. Reasoning: You (or the framework used) is calling the GoBack() explicitly, so why would it have to be cancelled in this scenario.
Regarding this question: Is it possible to force a page constructor call on windows phone?
Background:
I am writing a Windows Phone application with DirectX using SharpDX.Toolkit. When navigating back from another page, some re-initialization has to be done. In the provided samples, this is done using the constructor, which works. However, if I place the initialization code into the page loaded event (since the constructor on my page is not called), the initialization does no longer work.
This re-initalization is not needed (and, in fact, introduces bugs into the application), when the navigation is a back navigation from another application or the navigation is induced by a fast app switch. Therefore, overloading the NavigatedTo method is not sufficient.
If you want some code to be launched every time user navigates to your page, just override the OnNavigatedTo or OnNavigatedFrom method:
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// this method is called on each navigation to the page
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatingFrom(e);
// this method is called on each navigation from the page
}
I want to let the user decides if he wants to do a last request at my app when the the Windows is shutting down or logging off. So I am using the "SessionEnding" event.
The following code is triggered but doesn't work. Here is the simplest example:
public App()
{
this.SessionEnding += App_SessionEnding;
}
void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
e.Cancel = true;
}
I am afraid that I've used a boost program before in my computer (like CCleaner), and somehow it deactivated this event. =O
When I add a MessageBox to the event, and I request to log off my computer, then the MessageBox appears, but I don't have time to click somewhere because after 1 second, the system log off. The system seems to not be waiting for my application.
Obs: I am using Windows 7.
I tried a sample of your code without success ... however I put this into my main window that causes the application to close and the MessageBox was displayed indefinitely until I clicked close. Could this help?
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
MessageBox.Show("Blah", "Blah", MessageBoxButton.OK);
base.OnClosing(e);
}
Try overriding the event handler that's already there.
https://wpf.2000things.com/2011/01/25/197-override-application-class-methods-for-standard-events/
public partial class App : Application
{
protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
{
// Always call method in base class, so that the event gets raised.
base.OnSessionEnding(e);
// Place your own SessionEnding logic here
}
}
I am trying to determine if my application is closed through clicking the "X" on the windows form, or if they clicked an "Exit" button I have on it. Right now I am using StackTrace.GetFrame(someIndex) to determine how, but i am looking for a more definitive way since it looks like these frame orders arent guaranteed. Is there a better way to make the distinction? This is a .NET 3.5 WinForm, and Im writing in C#.
Use a different event to handle your own "Exit" button click. In your own "Exit" event handler do your extra logic, or set some state variable, and then call the normal application close method.
Post some samples of how your events are wired up and I get give a more specific example. In general it would look something like this:
private void btnMyExit_Click(object sender, EventArgs e)
{
// TODO: add any special logic you want to execute when they click your own "Exit" button
doCustomExitWork();
}
public static void OnAppExit(object sender, EventArgs e)
{
doCustomExitWork();
}
private void doCustomExitWork()
{
// TODO: add any logic you want to always do when exiting the app, omit this whole method if you don't need it
}
Use the FormClosing event and query the FormClosingEventArgs for the enum CloseReason value.