How to delay xaml dialog on button click

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 :)

ItemClicked event is not supported as an EventTriggerBehavior within ListItemTemplate

I’ve been working on writing some code samples for our Universal Windows Platform, they really are pretty neat how they enable a single app to run across Windows desktop, phone, Xbox One, and even HoloLens eventually. We’ll have the code sample released in the near future, but for now I wanted to blog about some small issues I’ve run into, couldn’t find any relevant documentation or stackoverflow answers, and I ended up figuring out the solutions on my own.
In this case, we were creating a listview and each item we wanted to be clickable to navigate to a detail page regarding that item. The listview control does have a selected item functionality built in, but we didn’t want to use that. A simple command to execute when one of the items is clicked is exactly what we wanted.
<DataTemplate x:Key="ListItemTemplate"> <interactivity:Interaction.Behaviors>
  <core:EventTriggerBehavior EventName="ItemClick">
    <core:InvokeCommandAction
      Command="{Binding DataContext.FooCommand, ElementName=LayoutRoot}"
      CommandParameter="{Binding}" />
    </core:EventTriggerBehavior>
  </interactivity:Interaction.Behaviors>
</DataTemplate>

<ListView ItemsSource="{Binding TheItems}"
  IsItemClickEnabled="True" SelectionMode="None"
  ItemTemplate="{StaticResource ListItemTemplate}" />
 Seems like this will get the job done, but compiler kept throwing us this very helpful error.
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 27 Position: 95]
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.InvokeCommandAction' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 29 Position: 99]
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 28 Position: 95]

Well, after a bit of digging I found out that a data template does not support an event trigger behavior for the event name as ItemClick. The ItemClick event is actually specific to the ListView xaml control, which is why the compiler complains that it cannot be added to the BehaviorCollection, so in our event trigger behavior we had to use a different event entirely. The Tapped event is the event we want, it is a high level event to cover both touch and mouse interactions.

<DataTemplate x:Key="ListItemTemplate">
   <interactivity:Interaction.Behaviors>
      <core:EventTriggerBehavior EventName="Tapped">
         <core:InvokeCommandAction
            Command="{Binding DataContext.FooCommand, ElementName=LayoutRoot}"
            CommandParameter="{Binding}" />
      </core:EventTriggerBehavior>
   </interactivity:Interaction.Behaviors>
</DataTemplate>

<ListView ItemsSource="{Binding TheItems}
  IsItemClickEnabled="True" SelectionMode="None"
  ItemTemplate="{StaticResource ListItemTemplate}" />
 There we go. Now, when a user clicks, or touches, one of the items shown in the ListView, the proper trigger is fired.  Hope this helps!