Search code examples
c#navigationwindows-phoneuwp

How to execute command saved in tile with an UWP app while it's running?


I have an app which pins a secondary tile on the start screen with a certain command stored in the tile.

  1. If the application is running or is in the background, and I tap the pinned tile, the app is unable to get the parameter from the tile, because the OnNavigatedTo method of the MainPage is not called.
  2. If I close/terminate the application, the OnNavigatedTo method is called, thus I can get the parameters from the tile.

At point 1 the OnNavigatedTo is not called because in the App.xaml.cs the navigation to the MainPage is only if it hasn't been set as the content of the rootFrame:

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(Views.MainPage), e.Arguments);
}

So, when rootFrame.Content is not null, the MainPage.OnNavigatedTo is not called.

I tried solving the problem by removing the if statement above, but then the MainPage get's instantiated every time the tile is tapped. So, two times if I start the app from the app list and then tap the tile.

I'd like the tile to start the application when it's not running, and also execute its stored command when the app is running, without instantiating the MainPage a second time.

Is there a best practice way to avoid this situation? Should I just handle the tile command in the App.xaml.cs?:

//...
else
{
    if (e.PreviousExecutionState == ApplicationExecutionState.Running || e.PreviousExecutionState == ApplicationExecutionState.Suspended)
    {
         var mainPage = rootFrame.Content as Views.MainPage;
         if (mainPage != null)
         {
             string command = e.Arguments;
             if (!String.IsNullOrWhiteSpace(command) && command.Equals(Utils.DefaultTileCommand))
             {
                  await mainPage.HandleCommand(command);
             }
         }
     }
}

Thanks


Solution

  • The tile arguments are passed to your App.xaml.cs OnLaunched method.

    If you want your MainPage to receive the arguments, you'll have to add some special logic. You can determine that you were launched from a secondary tile by checking the TileId (which will be "App" unless you've manually edited your app manifest). And then you can determine if the MainPage is currently displayed, and if so, call a method that you've added on the MainPage to pass the arguments to the current instance.

    Here's the code...

    protected override async 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(Views.MainPage), e.Arguments);
        }
    
        // If launched from secondary tile and MainPage already loaded
        else if (!e.TileId.Equals("App") && rootFrame.Content is MainPage)
        {
            // Add a method like this on your MainPage class
            (rootFrame.Content as MainPage).InitializeFromSecondaryTile(e.Arguments);
        }
    
        ...