如何在 WPF 中为 DataGridColumnHeader 创建工具提示?

How to create ToolTip for DataGridColumnHeader in WPF?

我找到了如何在 WPF 中为 DataGridColumnHeader 创建 ToolTip(并确保 Header 被包装)。

<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>

我可以这样使用这种风格:

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

这个解决方案不是很好,因为我需要为每个 header 创建一个单独的样式,因为工具提示是固定在样式中的。我想要一个可以这样使用的通用样式:

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

知道怎么做吗?可以附上 属性?

您可以使用 DataGridTemplateColumn

<DataGrid AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="yourHeader" HeaderStyle={StaticResource HeaderStyle1}">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <!--you can add any control such as ComboBox, Button etc-->
                    <TextBlock Text="{Binding Message}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <!--Editing cell template is not mandatory, only if you want allow user to edit a particular cell, shown here only for reference-->
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <!--When the user double clicks on this cell, it changes the control to TextBox (from TextBlock - see above) to allow for user input-->
                    <TextBox Text="{Binding Message}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        <!--Second Column-->
        <DataGridTemplateColumn Header="secondHeader" HeaderStyle={StaticResource HeaderStyle2}">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemSource="{Binding SomeSource}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

这对于每一列来说似乎有点多。但它为您提供了更多的控制权和更好的可扩展性,以应对未来的复杂变化。它在最初的开发阶段投入了一些微不足道的工作。

至少这是我的观点,因为在这个概念取得成功之后,又出现了一些 inputs/changes 和新的要求,以通过 how/when 上的特定规则和逻辑来改善用户交互性,用户可以与 UI 元素,尤其是在更改数据时。

编辑 - 您的风格可以与您所做的完全一样,即定位 DataGridColumnHeader.

您可以在每一列上设置附加的 ToolTipService.ToolTip 属性 并将您的值绑定到它,因为它不在列上使用。

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

然后您可以使用 RelativeSource 绑定将此文本绑定到您的 header 样式的列上。

<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>

现在你只有一种风格。如果您想避免在每一列上设置样式,请通过省略 x:Key 使其成为隐式样式。然后它将应用于范围内的所有匹配类型。

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