DZone
Mobile Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Mobile Zone > MessageBox, Navigation and Application Life Cycle

MessageBox, Navigation and Application Life Cycle

Maarten Struys user avatar by
Maarten Struys
·
Feb. 07, 12 · Mobile Zone · Interview
Like (0)
Save
Tweet
2.66K Views

Join the DZone community and get the full member experience.

Join For Free

One of our applications failed certification today because of an issue I should have known about. Even though the scenario in which an exception occurs is fairly easy, solving the problem properly involves a little work and a little thinking. Other blog entries have been written about this particular problem, although suggested solutions did not seem to work for me. Let me first show the original code:

MessageBox and Navigation

    private void TurnCard_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        MessageBoxResult mr = MessageBoxResult.Cancel;
     
        if (nrTimesClicked > 2)
        {
            mr = MessageBox.Show("Continuing now might confuse you. Try again tomorrow?",
                "Continuing tomorrow?", MessageBoxButton.OKCancel);
        }
     
        if (mr == MessageBoxResult.OK)
        {
            NavigationService.GoBack();
        }
        else
        {
            Random r = new Random();
            int card = r.Next(cardPages.Length);
            NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
            nrTimesClicked++;
        }
    }

Running this code and clicking the Start button on the phone while the MessageBox is visible results in the following exception when running with the debugger attached (it results in an application termination when running stand-alone):



The NavigationFailed event is raised. This is caused by the fact that the MessageBox returns when clicking the phone’s Start button with a return value of MessageBoxResult.Cancel. Since in the above code fragment, the Cancel button is used to navigate to some page, even though the application is supposed to go to the background in order to display the start screen on the phone, navigation fails. The interesting part is that the application does not have a clue that the user pressed the Start button on the phone. So some thinking is required to fix this issue.

Single stepping through the problematic method TurnCard_Click showed another behavior:



This at least made clear that indeed the call to the NavigationService caused the problem. To solve the problem, what can be done is protecting calls to the NavigationService by catching this particular exception:

Protecting the Navigate Method

    private void TurnCard_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        MessageBoxResult mr = MessageBoxResult.Cancel;
     
        if (nrTimesClicked > 2)
        {
            mr = MessageBox.Show("Continuing now might confuse you. Try again tomorrow?",
                "Continuing tomorrow?", MessageBoxButton.OKCancel);
        }
     
        if (mr == MessageBoxResult.OK)
        {
            NavigationService.GoBack();
        }
        else
        {
            Random r = new Random();
            int card = r.Next(cardPages.Length);
            try
            {
                NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
            }
            catch (InvalidOperationException)
            {
                ;
            }
            nrTimesClicked++;
        }
    }

This does solve the problem, although I don’t like it that an exception is thrown in a situation that the operating system should somehow prevent us against (maybe by returning some other value when the MessageBox returns without the user clicking on one of its buttons). If you want to have a little more flexibility, and don’t mind coding a bit more, there is another possible solution. Instead of using a MessageBox, you can make use of the Guide.BeginShowMessageBox method that is defined in the XNA Framework. This method is a bit more complex, but also much more flexible then its Silverlight counterpart. BeginShowMessageBox is asynchronous, which means that you need to take care with calling code that is supposed to run on the UI Thread.

Using BeginShowMessageBox

    private void TurnCard_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        if (nrTimesClicked > 2)
        {
            ShowContinueMessage();
        }
        else
        {
            Random r = new Random();
            int card = r.Next(cardPages.Length);
            nrTimesClicked++;
            NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
        }
    }
     
    private void ShowContinueMessage()
    {
        List<string> mbOptions = new List<string>();
        mbOptions.Add("OK");
        mbOptions.Add("Cancel");
        string msg = "Continuing now might confuse you. Try again tomorrow?";
        string title = "Continuing tomorrow?";
        Guide.BeginShowMessageBox(title, msg, mbOptions, 0, MessageBoxIcon.Alert, EnteredAnswer, null);
        messageBoxVisible = true;
    }
     
    private void EnteredAnswer(IAsyncResult ar)
    {
        int? result = Guide.EndShowMessageBox(ar);
     
        if (result != null)
        {
            messageBoxVisible = false;
        }
     
        if (result != null && result == 0)
        {
            this.Dispatcher.BeginInvoke(delegate
            {
                NavigationService.GoBack();
            });
        }
        else if (result != null)
        {
            Random r = new Random();
            int card = r.Next(cardPages.Length);
            this.Dispatcher.BeginInvoke(delegate
            {
                NavigationService.Navigate(new Uri(cardPages[card], UriKind.Relative));
            });
        }
    }

The interesting code can be found in the EnteredAnswer method, where we retrieve the key the user entered in the message box. Since EndShowMessageBox returns a nullable integer, it has this nice way of using null in those cases where the user did not click any key (in other words, for instance when the message box is removed as a result of the application going to the background). So now we have a way of detecting if we can navigate (result has a value other then null). The sample code also sets a boolean variable messageBoxVisible, which is used in combination with MVPLinkExtension to display the message box again when the user returns to the application. Hopefully this time the application will pass certification.


Source: http://mstruys.com/2012/01/19/messagebox-navigation-and-application-life-cycle/


application

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Creating an Event-Driven Architecture in a Microservices Setting
  • Pattern Matching for Switch
  • Exhaustive JUNIT5 Testing with Combinations, Permutations, and Products
  • How to Translate Value to Executives Using an Outcome-Driven Mindset

Comments

Mobile Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo