Search code examples
c#wpfdatatemplate

Passing objects in ItemsControl using a DataTemplate


So basically I have a class Step.

public class Step : INotifyPropertyChanged
{
    public int Index { get; set; }
    public int Time { get; set; }
}

In my xaml, I want to represent Steps using one DataTemplate and an ItemsControl. My DataTemplate looks like this:

<DataTemplate x:Key="StepTemplate" DataType="data:Step">
    <Label Content="{Binding Index}"/>
    <Label Content="{Binding Time}"/>
</DataTemplate>

And my ItemsControl looks like this.

<ItemsControl Name="ListSteps" ItemsSource="{Binding Steps}" Grid.IsSharedSizeScope="True" ItemTemplate="{StaticResource StepTemplate}" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseLeftButtonDown">
            <i:InvokeCommandAction Command="{Binding Path=DataContext.StepClick, ElementName=ListSteps}" CommandParameter="{Binding}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ItemsControl>

So pretty much what should happen: Whenever I click on a Step, the method StepClick gets called and the Step object that I clicked on is passed as a parameter.

What is actually happening: Whenever I click on a Step, the method StepClick gets called, but not the Step Object gets passed as a parameter but an object of my view gets passed. Which is not at all what I want.

How can I pass an object of Step whenever I click on a Step?


Solution

  • Move the interaction trigger to the root element of the ItemTemplate:

    <DataTemplate x:Key="StepTemplate" DataType="data:Step">
        <StackPanel Background="Transparent">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <i:InvokeCommandAction Command="{Binding Path=DataContext.StepClick, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                                           CommandParameter="{Binding}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <Label Content="{Binding Index}"/>
            <Label Content="{Binding Time}"/>
        </StackPanel>
    </DataTemplate>