Search code examples
silverlightwindows-phone-8windows-phone-8.1dispatcher

Getting the current page when receiving a toast notification (WP8.1 Silverlight, receiving WNS toast notification)


I have an event that fires when the app is live and I receive an notification CurrentChannel_PushNotificationReceived. In this function I want to find out which page is currently displayed to know if the notification should update content on the page. The question is therefore twofold, how to know which page is currently displayed and interact with the toast notification.

Update The issue is that I cannot interact with the elements because of clash with the OS threading (Dispatcher).

Therefore using the below code it allows me to access the content of the message. But I am still not able to get the info of the current_page

  _channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
_channel.PushNotificationReceived += OnPushNotificationReceived;

private void OnPushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args) { switch (args.NotificationType) { case PushNotificationType.Badge: this.OnBadgeNotificationReceived(args.BadgeNotification.Content.GetXml()); break;

        case PushNotificationType.Tile:
            this.OnTileNotificationReceived(args.TileNotification.Content.GetXml());
            break;

        case PushNotificationType.Toast:
            this.OnToastNotificationReceived(args.ToastNotification.Content.GetXml());
            break;

        case PushNotificationType.Raw:
            this.OnRawNotificationReceived(args.RawNotification.Content);
            break;
    }

    args.Cancel = true;
}

private void OnBadgeNotificationReceived(string notificationContent)
{
    // Code when a badge notification is received when app is running
}

private void OnTileNotificationReceived(string notificationContent)
{
    // Code when a tile notification is received when app is running
}

private void OnToastNotificationReceived(string notificationContent)
{
    // Code when a toast notification is received when app is running

    // Show a toast notification programatically

    var xmlDocument = new XmlDocument();
    xmlDocument.LoadXml(notificationContent);
    var toastNotification = new ToastNotification(xmlDocument);

    //toastNotification.SuppressPopup = true;
    ToastNotificationManager.CreateToastNotifier().Show(toastNotification);
}

private void OnRawNotificationReceived(string notificationContent)
{
    // Code when a raw notification is received when app is running
}

Question

How do I access the current page information in the different onXXXXNotificationReceived. The current snippets work but not within these functions:

var currentPage = ((PhoneApplicationFrame)Application.Current.RootVisual).Content;
        var tempBool = currentPage.GetType() is BC_Menu.StartUp.SecondScreen;

or

RootFrame.CurrentSource;

My guess is it is because of the UI-thread. So how can I use the dispatcher to get the information? I have tried some solutions with the dispatcher, but I cannot await the information, and therefore it is not applicable.

System.Windows.Threading.DispatcherOperation op = App.RootFrame.Dispatcher.BeginInvoke(new Func<Uri>(() =>  
            {
                return RootFrame.CurrentSource;
            })
        );
        await op; //Not awaitable.

Solution

  • There's no reason to await the dispatcher to the UI thread. Simply dispatch to the UI thread and then perform the rest of your logic, like displaying the toast or navigating to a page, from within the UI thread...

    Register the event...

    var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    channel.PushNotificationReceived += Channel_PushNotificationReceived;
    

    On the event handler, cancel displaying the notification and then dispatch to UI thread...

    private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)
    {
        // Make sure you cancel displaying the toast on this thread (not on UI thread)
        // since cancellation needs to be set before this thread/method returns
        args.Cancel = true;
    
        // Then dispatch to the UI thread
        App.RootFrame.Dispatcher.BeginInvoke(delegate
        {
            var currPage = ((PhoneApplicationFrame)Application.Current.RootVisual).Content;
    
            switch (args.NotificationType)
            {
                case PushNotificationType.Toast:
                    // TODO
                    break;
            }
        });
    }
    

    Do all of your code inside the dispatcher's delegate. All your code will be executing on the UI thread... you'll be able to navigate pages, obtain current page, etc.