【问题标题】:How to create ToolTip for DataGridColumnHeader in WPF?如何在 WPF 中为 DataGridColumnHeader 创建工具提示?
【发布时间】:2021-02-07 03:54:55
【问题描述】:

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

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

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

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

知道怎么做吗?可能是附带财产?

【问题讨论】:

    标签: wpf xaml datagrid tooltip attached-properties


    【解决方案1】:

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

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

    然后您可以使用RelativeSource 绑定将该文本绑定到标题样式中的列上。

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

    【讨论】:

    • 这正是 OP 试图避免的。他想设置工具提示样式,而不是为每一列创建标题样式
    • @Bandook 不,他在这里创建了一个 single 样式,它不会硬连线工具提示文本。
    • 谢谢@thatguy 您的回答并不完美(缺少触发器),但它引导我来到这里stackoverflow.com/a/2052199/5852947
    • @IstvanHeckl 抱歉,我错过了什么吗?缺少哪个触发器?在链接的答案中有一个IsMouseOver 触发器,但这不是必需的,因为无论如何只有在鼠标悬停时才会显示工具提示。我已经对其进行了测试,并且列标题工具提示按预期显示,触发器对我没有任何改变。
    • 嗨@thatguy!对我来说,IsMouseOver 是必需的,没有它,工具提示就不会出现。
    【解决方案2】:

    你可以使用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>
    

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

    至少这是我的看法,因为在这个概念成功之后,一些进一步的输入/更改和新要求会通过特定规则和逻辑来改善用户交互性,这些规则和逻辑涉及用户如何/何时与 UI 元素交互,尤其是在更改数据时。

    编辑 - 你的风格可以和你做的一模一样,即定位DataGridColumnHeader

    【讨论】:

    • 亲爱的@Bandook。我过去使用过DataGridTemplateColumn。我的问题集中在HeaderStyle。我不想为每列创建新样式。不知何故,我想避免 HeaderStyle 中的硬连线工具提示。
    • 您希望工具提示仅应用于标题(即不是数据行) - 这只能通过 HeaderStyle 进行控制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    相关资源
    最近更新 更多