2

I have made a custom messagebox (discussed here) that shows localized quit prompt.

protected override void OnBackKeyPress(CancelEventArgs e)
{
    //some conditions
    e.Cancel = true;
    string quitText = DeviceWrapper.Localize("QUIT_TEXT");
    string quitCaption = DeviceWrapper.Localize("QUIT_CAPTION");
    string quitOk = DeviceWrapper.Localize("DISMISS");
    string quitCancel = DeviceWrapper.Localize("MESSAGEBOX_CANCEL");
    IAsyncResult asyncResult = Guide.BeginShowMessageBox(
quitCaption, quitText, new List<string> { quitOk, quitCancel }, 
0, MessageBoxIcon.Error, null, null);
    asyncResult.AsyncWaitHandle.WaitOne();
    int? result = Guide.EndShowMessageBox(asyncResult);
    if (result.HasValue && result.Value == 0)
        e.Cancel = false;
    //some more features
}

It works fine, but it does crash when it's run as stand-alone (without Visual Studio) after few seconds if user doesn't press anything.

I tried reproducing the same crash with phone attached using Release and Debug from Visual Studion, but it's as stable as it can possibly be. It only crashes when app is run from the phone itself.

How do I find the issue? What could be the reason for it? As far as I can tell, I cannot access crash logs on the device. There should be something with the messagebox logic perhaps?

UPD Few notes on your suggestion, Neil:

first of all VS warns me "the async method lacks await" stuff.

secondly I am not sure how to return info to "BackKeyPressed" that e.Cancel should equal "false". This should be the safe way to quit an app AFAIK.

And wouldn't we quit the "OnBackKeyPress" method if we run async method from it? That would mean that we can't let it know about our decision (e.Cancel = false).

Or if we don't quit the "OnBackKeyPress" then it could mean this event will stay for too long and the whole purpose is lost - app will be killed, right?

UPD2:

It seems that I am between Scylla and Charybdis: either I show a messagebox and experience crashes in runtime which is discouraged by guidelines, or I don't show a messagebox at all.

I've tried both native MessageBox and my implementation of custom messagebox with localized "Ok" and "Cancel" buttons. They behave the same: either they are synchronous and hang OnBackKeyPress, or they are async and OnBackKeyPress exits before we can let it know about user's decision.

Final decision

Apparently the guidelines state that we shouldn't ask user's confirmation at all. Since there is no viable way to implement a working quit confirmation messagebox without crashing I've decided to not show it at all.

2 Answers 2

1

If you block or delay certain page events for too long, the OS will kill your app as it assumes its crashed...

  • OnNavigatedTo
  • OnNavigatedFrom
  • OnBackKeyPress

In your case, I would recommend putting the custom MessageBox in it's own method, then calling it on the UI thread.

private void customMessageBox()
{
    // custom message box code
    // use NavigationService.GoBack() if you need to exit
}

protected override void OnBackKeyPress(CancelEventArgs e)
{
    e.Cancel = true;
    Deployment.Current.Dispatcher.BeginInvoke(() => customMessageBox() );
}

I also found another answer which accomplishes the thing by making the method Async.


Debugger attached (or not)

When the Visual Studio debugger is attached, the OS does not warn you of certain errors such as high memory usage, page init delays, etc - so it is very important to test your app without the Visual Studio debugger attached either on device or in the emulator (Debug or Release)


Windows Phone 8.1

Be aware that the handling of the Back button has changed in WP8.1 XAML/WinRT apps. It might be something to consider if you're upgrading the app project in future.

7
  • Sounds logical. I'll try it and will let you know. What about crash not reproducing when attached to MSVS though? Why don't I see it there?
    – Protheus
    Commented Jul 23, 2014 at 15:47
  • @Protheus I'll add more info to the answer. Commented Jul 23, 2014 at 15:50
  • I have updated the question with follow-up questions. Regarding your explanation of MSVS and debugs - thanks a lot!
    – Protheus
    Commented Jul 23, 2014 at 16:14
  • @Protheus I've updated the answer and fixed a mistake, hopefully it makes more sense now? Commented Jul 23, 2014 at 22:23
  • Same as Taeb's answer: this is async method and I cannot get OnBackKeyPressed to know that e.Cancel should be false for it to appropriately exit an app.
    – Protheus
    Commented Jul 24, 2014 at 8:11
0

I implemented this in my project and it worked. Try it!

 protected override void OnBackKeyPress(CancelEventArgs e)
        {


            base.OnBackKeyPress(e);
            e.Cancel = true;
            Deployment.Current.Dispatcher.BeginInvoke(() =>
                           {
                               MessageBoxResult result = MessageBox.Show("Hello", "Msg Box", MessageBoxButton.OKCancel);
                               if (result == MessageBoxResult.OK)
                               {
                                   //Do something
                               }
                               else
                               {
                                   //Do something
                               }
                           });



        }
2
  • This is async method and OnBackKeyPress doesn't get e.Cancel = false to appropriately exit an app. I did try that method before, it didn't work unfortunately.
    – Protheus
    Commented Jul 24, 2014 at 8:09
  • copy and paste the code in your project. The dispatcher does the needful for you. It should work Commented Jul 25, 2014 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.