Search code examples
c#wpfcontroltemplatedatatrigger

Datatrigger Binding to a property of the style's TargetType within a ControlTemplate and ContentPresenter


I'm creating a style for WPF ToolTips. The tooltips are a textbox with an arrow pointing to the control owning the tooltip. The arrow needs to be either on the left or right of the textbox, depending on whether the ToolTip.Placement is Right or Left.

To do this, I'm creating both a Right and Left arrow, and trying to use a datatrigger to bind to the Placement property so that I can set the arrow's visibility.

Right now, both arrows are always showing. I'm thinking that my datatriggers are not set up to bind to the ToolTip's Placement property, but I don't know what's wrong.

     <Style TargetType="ToolTip">
        <Setter Property="Placement" Value="Right" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToolTip">
                    <ContentPresenter>
                        <ContentPresenter.Content>
                            <StackPanel Orientation="Horizontal" >

                                <Path x:Name="LeftArrow" Fill="DarkOrange" Data="M 0 0 L 12 9 L 12 -9 Z" VerticalAlignment="Center" Stretch="Uniform">
                                    <Path.Style>
                                        <Style TargetType="Path">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding Placement}" Value="Right">
                                                    <Setter Property="Visibility" Value="Collapsed" />
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Path.Style>
                                </Path>

                                <TextBox Background="DarkOrange" Height="50" Width="50" />

                                <Path x:Name="RightArrow" Fill="DarkOrange" Data="M 0 0 L -12 -9 L -12 9 Z" VerticalAlignment="Center" Stretch="Uniform">
                                    <Path.Style>
                                        <Style TargetType="Path">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding Placement}" Value="Right">
                                                    <Setter Property="Visibility" Value="Collapsed" />
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Path.Style>
                                </Path>

                            </StackPanel>
                        </ContentPresenter.Content>
                    </ContentPresenter>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Solution

  • Template is overriden therefore you need to use TemplatedParent. Check value either to Left or Right since in your both cases DataTrigger checks for Right.

    <Path x:Name="RightArrow" Fill="DarkOrange" Data="M 0 0 L -12 -9 L -12 9 Z" VerticalAlignment="Center" Stretch="Uniform">
        <Path.Style>
                 <Style TargetType="Path">
                  <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Placement}" Value="Right">
                      <Setter Property="Visibility" Value="Collapsed" />
                    </DataTrigger>
                  </Style.Triggers>
                 </Style>
          </Path.Style>
    </Path>