0

Many articles let the DataTemplate item which is inside the DataTemplate have a Command, but I don't want to do so.

I want to add a Click Command to the DataTemplate itself, not to the Item inside the DataTemplate. Like when I click the DataTemplate anywhere it should fire the Command, can any body teach me?

Thanks!

Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65
Bing Feng
  • 71
  • 2
  • 11

1 Answers1

1

If I understand your question correctly, you can use an EventTrigger in combination with InvokeCommandAction like in the following code:

First, add this namespace definition:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

and then in your DataTemplate definition:

<DataTemplate>
    <Label Content="{Binding}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDown">
                <i:InvokeCommandAction Command="{Binding Path=DataContext.YourClickCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourControl}}}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Label>
</DataTemplate>

For above code to work you need to add the System.Windows.Interactivity assembly to your project by going to Add Reference > Assemblies > Extensions.

EDIT: I believe I now understand your question correctly. When you say you want to add the Command

on datatemplate, and I don't want to add command inside datatemplate item

you mean you want to write your code like <DataTemplate Command="{...}"> or <DataTemplate Click="...">.

On the one hand that is not possible because DataTemplate does not derive from DependencyObject, and on the other hand that is not even necessary.

If you want the MouseDown event to fire when the ListBoxItem is clicked, no matter what part of its template is clicked, you can wrap the DataTemplates template in a Grid (or StackPanel or any other container) and apply the Interaction.Triggers to that container:

<DataTemplate>
    <Grid Background="Transparent">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDown">
                <i:InvokeCommandAction Command="{Binding Path=DataContext.YourClickCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourControl}}}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <Label Content="{...}" />
        <Label Content="{...}" />
        <Label Content="{...}" /> 
    </Grid>
</DataTemplate>

Now regardless of what label you clicked, the MouseDown event will always fire (note that for this to work you need to give the container a background, else the hit test does not work).

Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65
  • First thanks for your answer, in addition, I would like to ask, in addition to this method whether there are other practices, thanks! – Bing Feng Sep 07 '17 at 14:37
  • So do you want to be able to use the command in the `DataTemplate` without specifying it there? If so, give me a few minutes, I am already working on an example for that. – Thomas Flinkow Sep 07 '17 at 14:38
  • Yes, like your current method, but i want some different method without add Interactivity.dll to keep the project simple. – Bing Feng Sep 07 '17 at 14:43
  • @BingFeng as far as I know, there are not _inbuilt_ ways to do that (_inbuilt_ referring to the fact that they are not contained in the .dlls Visual Studio already added as references for you, such as `System.Xaml` or `WindowsBase`), but you could go with [MVVM Lights `EventToCommand`](http://mvvmlight.codeplex.com/) even though this does essentially the same for you. – Thomas Flinkow Sep 07 '17 at 14:51
  • 1
    Thomas thanks for your help, it really helpful for me. I will try it. – Bing Feng Sep 07 '17 at 14:55