Search code examples
c#mvvmuwpwinui-3behavior

WinUI 3 ListView item double tapped behavior not working inside datatemplate


I'm trying to add a behavior to the DoubleTapped event of a ListViewItem inside a data template.

     <Button.Flyout>
     <Flyout>
         <Grid Height="500">
             <ListView ItemsSource="{x:Bind ViewModel.AvailableProperties, Mode=OneWay}">
                 <ListView.ItemTemplate >
                     <DataTemplate x:DataType="properties:PropertyDefinition">

                         <StackPanel Padding="10,5,10,5" x:Name="listViewItem">

                             <interactivity:Interaction.Behaviors>
                                 <core:EventTriggerBehavior 
                                     EventName="DoubleTapped" 
                                     SourceObject="{Binding ElementName=listViewItem}">

                                     <core:InvokeCommandAction 
                                     Command="{Binding ElementName=bomPage, Path=ViewModel.AddPropertyCommand}" 
                                     CommandParameter="{x:Bind}"/>

                                 </core:EventTriggerBehavior>
                             </interactivity:Interaction.Behaviors>

                             <TextBlock Text="{x:Bind PropertyName}" />
                             <TextBlock Text="{x:Bind PropertySetName}" />
                         </StackPanel>

                     </DataTemplate>
                 </ListView.ItemTemplate>
             </ListView>
         </Grid>
     </Flyout>
 </Button.Flyout>

The behavior works fine when I move the stackpanel out of the datatemplate, but it doesn't work when it is inside. Am I doing something wrong? Is it possible to attach the behavior as I'm trying?


Solution

  • I am afraid you cannot bind to the parent Page using the ElementName property inside a DataTemplate because the elements reside in different XAML namescopes.

    You might just invoke the command from the code-behind of the view though:

    private void listViewItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        StackPanel stackPanel = sender as StackPanel;
        ViewModel.AddPropertyCommand.Execute(stackPanel?.DataContext);
    }
    

    XAML:

    <StackPanel Padding="10,5,10,5" x:Name="listViewItem"
                DoubleTapped="listViewItem_DoubleTapped">
    
        <TextBlock Text="{x:Bind PropertyName}" />
        <TextBlock Text="{x:Bind PropertySetName}" />
    </StackPanel>
    

    This is not any worse than using an InvokeCommandAction from an MVVM point of view. The very same view invokes the very same view model command - in an even less verbose way actually.