Search code examples
wpfxamldatagridtooltipattached-properties

How to create ToolTip for DataGridColumnHeader in WPF?


I have found how to create ToolTip for DataGridColumnHeader in WPF (and make sure that the Header is wrapped).

<Style x:Key="StartingTabToolTipHeaderStyle" TargetType="DataGridColumnHeader">
   <Setter Property="ToolTip" Value="{x:Static r:Resource.StartingTabToolTip}"/>
   <Setter Property="ContentTemplate">
      <Setter.Value>
         <DataTemplate>
            <TextBlock TextWrapping="Wrap" Text="{Binding}"/>
         </DataTemplate>
      </Setter.Value>
   </Setter>
</Style>

I can use this style in this way:

<DataGridComboBoxColumn Header="{x:Static r:Resource.StartingTab}" SelectedItemBinding="{Binding StartingTab}" 
                        HeaderStyle="{StaticResource StartingTabToolTipHeaderStyle}">

This solution is not nice because I need to create a separate style for each header because the tooltip is hardwired in the style. I would like a general style which can be used in this way:

<DataGridComboBoxColumn Header="{x:Static r:Resource.StartingTab}" SelectedItemBinding="{Binding StartingTab}" 
                        MyToolTip="{x:Static r:Resource.StartingTabToolTip}">

Any idea how to do it? May be with attached property?


Solution

  • You can set the ToolTipService.ToolTip attached property on each column and bind your values to it, because it is not used on columns.

    <DataGridComboBoxColumn Header="{x:Static r:Resource.StartingTab}"
                            SelectedItemBinding="{Binding StartingTab}" 
                            HeaderStyle="{StaticResource StartingTabToolTipHeaderStyle}"
                            ToolTipService.ToolTip="{x:Static r:Resource.StartingTabToolTip}">
    

    Then you can bind this text on the column in your header style using a RelativeSource binding.

    <Style x:Key="StartingTabToolTipHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
       <Setter Property="ToolTip" Value="{Binding Column.(ToolTipService.ToolTip), RelativeSource={RelativeSource Self}}"/>
       <Setter Property="ContentTemplate">
          <Setter.Value>
             <DataTemplate>
                <TextBlock TextWrapping="Wrap" Text="{Binding}"/>
             </DataTemplate>
          </Setter.Value>
       </Setter>
    </Style>
    

    Now you only have a single style. If you want to avoid setting the style on each column, make it an implicit style by omitting the x:Key. Then it will be applied to all matching types in scope.

    <Style TargetType="{x:Type DataGridColumnHeader}">