Search code examples
wpfbindingdatatemplate

How to bind CommandParameter to x:name of parent control in DataTemplate?


I have the following in my View XAML

<GroupBox Grid.Row="0" Header="Aktionen bei Prüfung Aufbau">
    <ContentControl Content="{Binding BuildUpActions}" ContentTemplate="{StaticResource FullActionListTemplate}" x:Name="BuildUp"/>
</GroupBox>

<GroupBox Grid.Row="1" Header="Aktionen bei Prüfung Abbau">
    <ContentControl Content="{Binding TearDownActions}" ContentTemplate="{StaticResource FullActionListTemplate}" x:Name="TearDown"/>
</GroupBox>

The DataTemplate is defined in a separate resource

<DataTemplate x:Key="FullActionListTemplate">
    <DockPanel LastChildFill="True">
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Content="Neuer Ausgang" Style="{StaticResource ButtonRowStyle}"
                    Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}, Path=DataContext.NewFullIOCommand}" 
                    CommandParameter="{Binding **?HOW?**}"
                    />
            <more buttons here...>
        </StackPanel>
        <ContentControl Content="{Binding}" >

        </ContentControl>
    </DockPanel>
</DataTemplate>

The Command is defined in the ViewModel

    public ICommand NewFullIOCommand
    {
        get
        {
            if (this._newFullIOCommand == null)
            {
                this._newFullIOCommand = new Mvvm.RelayCommand(parm => DoNewFullIO(parm));
            } return this._newFullIOCommand;
        }
    }

I want to be able to determine which of the 2 lists generated the Command. I want a CommandParameter to be passed to the command handler which contains the x:Name of the control.

How do I define the binding? Is there a better way?


Solution

  • I took a look at your sample and did a quick edit of the line reading the CommandParameter. After doing this change I inspected this in Snoop (WPF runtime debugger) and saw the CommandParameter being set to the one you described as the desired values to apply.

    First off, you can obtain Snoop here:

    Snoop

    I was able to set the CommandParameter to the name of the enclosing ContentControl by simple doing this:

    <DataTemplate x:Key="FullActionListTemplate">
            <DockPanel LastChildFill="True">
                <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
                    <Button Content="Neuer Ausgang"
                    Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}, Path=DataContext.NewFullIOCommand}" 
                    CommandParameter="{Binding Path=Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"
                    />
                </StackPanel>
                <ContentControl Content="{Binding}" >
    
                </ContentControl>
            </DockPanel>
        </DataTemplate>
    

    As a side note, your example almost contain a similar technique on the line above, where you bind to the Command property.