When using a ContentDialog in UWP to allow the user to make some kind of action that depends on a service or other asynchronous call, you probably want to ensure that call completes correctly before dismissing the dialog window. Otherwise, the result is just forgotten about. In our UWP sample app, users can give gold to a particular photo they like and leave a comment. In the GiveGoldDialog the user inputs their comment text and then presses the “ok” button, which the app then fires off actions to handle gold balance transactions and creating the comment on the photo. Before dismissing the GiveGoldDialog, we wanted to be sure that those calls completed.
When handling the PrimaryButtonClick event, before initiating the actions get a ContentDialogButtonClickDeferral object from the ContentDialogButtonClickEventArgs parameter. Creating this deferral object will prevent the button click from finishing until you complete it, suspending(or canceling) the dialog from closing until your service call finishes. Based on your service’s actions, you can even stop the dialog’s button click from closing the dialog by setting the args’ Cancel parameter to true. This could be done to tell the user that the request wasn’t able to complete and try again or that maybe their content failed some kind of validation. In our sample app we would cancel the the action if the user’s gold balance was too low to complete the transaction.
async void Dialog_PrimaryButtonClick( ContentDialog sender, ContentDialogButtonClickEventArgs args ) { // // Get the deferral because we need to await the // annotation to post. // var deferral = args.GetDeferral(); // // Get creation status and if failed, let's // keep the dialog opened. // var success = await ViewModel.MakeFooServiceCall(); args.Cancel = !success; // // Complete deferral to close the dialog. // deferral.Complete(); }
When we originally wrote this code, the deferral object wasn’t very well documented and it took us some digging to figure out what it was and how to use it. Now it seems to be well documented within an example, but maybe this post will still help someone :)