The Windows Phone Toolkit is really useful.
Yesterday, while I was updating my ConsoTracker app, I met a strange bug using the CustomMessageBox : it was raising a nullReference exception.
Let’s see what was the issue and how to “fix” it.
What I was trying to do was this simple scenario :
- Ask the use if he wants to review my app in the OnNavigatedTo event using a CustomMessageBox
- If he answers ‘no’, navigate to another page.
- If it answers ‘yes’, show the marketplace review task.
As I like playing with tasks, I was using this code :
[csharp]
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var mBox = new CustomMessageBox
{
Title = "Do you want to… ",
Message = " … click on yes ?",
LeftButtonContent = "Yes",
RightButtonContent = "No"
};
var result = await ShowAsync(mBox);
NavigationService.Navigate(new Uri("/OtherPage.xaml", UriKind.RelativeOrAbsolute));
}
public static async Task<CustomMessageBoxResult> ShowAsync(CustomMessageBox box)
{
var taskCompletionSource = new TaskCompletionSource<CustomMessageBoxResult>();
box.Dismissed += (a, b) => taskCompletionSource.TrySetResult(b.Result);
try { box.Show(); }
catch (Exception exception) { taskCompletionSource.TrySetException(exception); }
return await taskCompletionSource.Task;
}
[/csharp]
This code was throwing an exception. To fix it, I downloaded the source of the Windows Phone Toolkit and I saw that at the end of the dismissal animation, it was trying to access the “Popup” object which was null : BOUM !
So… how did I fix it ? Simply by waiting for the popup to be unloaded instead of using directly the Dismissed event of the CustomMessageBox :
[csharp]
public static async Task<CustomMessageBoxResult> ShowAsync(CustomMessageBox box)
{
var taskCompletionSource = new TaskCompletionSource<CustomMessageBoxResult>();
var result = CustomMessageBoxResult.None;
//Only store the result here.
box.Dismissed += (a, b) => result = b.Result;
//Use this event to set the result.
box.Unloaded += (_, __) => taskCompletionSource.TrySetResult(result);
try { box.Show(); }
catch (Exception exception) { taskCompletionSource.TrySetException(exception); }
return await taskCompletionSource.Task;
}
[/csharp]
I hope it will save you some time too 🙂