wpfdatatemplate

Accesing the Tag Element from Content Control and access it inside the Data Template


I have a ContentControl where I am setting its content to a DataTemplate. I am setting the Tag value of the ContentControl. Is there a way to access this Tag Element in the Data Template and pass it as CommandParameter? In other words I am trying to pass the Tag as a parameter to the DataTemplate.

   <DataTemplate x:Key="SensorStatusControlTemplate" x:DataType="viewModel:SensorBufferState">
                <Grid>
                    <Rectangle x:Name="SensorRectangle"
                               Fill="{x:Bind Converter={StaticResource SensorStateOverflowConverter},
ConverterParameter={What do I say here to get the Tag}}"
                               Height="30"
                               Width="125" />
                    <TextBlock x:Name="SensorTextBlock"
                               Text="{x:Bind Converter={StaticResource SensorStateOverflowConverter}}"
                               FontSize="{StaticResource FontSizeMedium}"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Foreground="White" />
                </Grid>
            </DataTemplate>

Here is my ControlTemplate. Is there a way to access the Tag in the DataTemplate?

<ContentControl Content="{Binding VmPRWControlData.OverflowSensorState,UpdateSourceTrigger=PropertyChanged}"
                                        ContentTemplate="{StaticResource SensorStatusControlTemplate}"
                                        Tag="Overflow"
                                        HorizontalAlignment="Center"
                                        Width="{Binding ElementName=LABLidSensorTextBlock,Path=ActualWidth}" />

Edit: I have tried doing like this but the parameter value is null,

ConverterParameter={Binding Tag, RelativeSource={RelativeSource Mode=TemplatedParent}}

Solution

  • You should traverse the tree to find the parent control using RelativeSource.AncestorType:

    <DataTemplate DataType="{x:Type viewModel:SensorBufferState}">
      <Button CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Tag}"/>
    </DataTemplate>
    

    As you correctly mentioned UWP doesn't support RelativeSource.AncestorType.

    The following solutions work with WPF too:

    Solution 1

    You can use Binding.ElementName instead

    App.xaml

    <DataTemplate x:Key="DataTemplate">
      <Button CommandParameter="{Binding ElementName=ContentControl, Path=Tag}"/>
    </DataTemplate>
    

    MainPage.xaml

    <ContentControl x:Name="ContentControl" 
                    Tag="123"  
                    ContentTemplate="{StaticResource DataTemplate}" />
    

    Solution 2

    Or alternatively use the DataContext set to a view model or a DependencyProperty instead of the Tag property:

    App.xaml

    <DataTemplate x:Key="DataTemplate">
      <Button CommandParameter="{Binding CommandParameterValue}"/>
    </DataTemplate>
    

    MainPage.xaml.cs

    public sealed partial class MainPage : Page
    {
      public static readonly DependencyProperty CommandParameterValueProperty = DependencyProperty.Register(
        "CommandParameterValue",
        typeof(string),
        typeof(MainPage),
        new PropertyMetadata(default(string)));
    
      public string CommandParameterValue 
      { 
        get => (string) GetValue(MainPage.CommandParameterValueProperty); 
        set => SetValue(MainPage.CommandParameterValueProperty, value); 
      }
    
      public MainPage()
      {
        this.InitializeComponent();
        this.DataContext = this;
        this.CommandParameterValue = "ABC";
      }
    }
    

    MainPage.xaml

    <ContentControl ContentTemplate="{StaticResource DataTemplate}" />