You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建启用/禁用状态显示不同ToolTip的可复用WPF按钮

解决WPF可复用按钮启用/禁用状态下ToolTip切换问题

问题说明

需要实现一个可复用的WPF Button,要求在启用和禁用状态下分别显示不同的ToolTip。当前实现存在以下问题:

  • 按钮启用状态无法显示对应的EnabledToolTip,禁用状态可正常显示DisabledToolTip
  • 调试时执行XAML热重载(无代码修改)后,两种状态的ToolTip均能正常显示
  • 尝试在EnabledToolTip和DisabledToolTip的setter中直接设置ToolTip,结果始终显示启用状态的ToolTip

现有代码

ButtonDualToolTip.xaml

<Button x:Class="ButtonDualToolTip"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        ToolTipService.ShowOnDisabled="True">
   <Button.Style>
      <Style TargetType="Button">
         <Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="True">
               <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=EnabledToolTip}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="False">
               <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=DisabledToolTip}" />
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </Button.Style>
</Button>

ButtonDualToolTip.xaml.cs

public partial class ButtonDualToolTip : Button
{
   public ButtonDualToolTip()
   {
      InitializeComponent();
   }

   public string EnabledToolTip
   {
      get { return (string)GetValue(EnabledToolTipProperty); }
      set { SetValue(EnabledToolTipProperty, value); }
   }

   public static readonly DependencyProperty EnabledToolTipProperty =
       DependencyProperty.Register(nameof(EnabledToolTip), typeof(string), typeof(Field), new PropertyMetadata());

   public string DisabledToolTip
   {
      get { return (string)GetValue(DisabledToolTipProperty); }
      set { SetValue(DisabledToolTipProperty, value); }
   }

   public static readonly DependencyProperty DisabledToolTipProperty =
       DependencyProperty.Register(nameof(DisabledToolTip), typeof(string), typeof(Field), new PropertyMetadata());
}

使用示例

<CheckBox x:Name="toolTipController"
          Content="Button enabled" />

<usercontrols:ButtonDualToolTip Content="Test"
                                EnabledToolTip="enabled"
                                DisabledToolTip="disabled"
                                IsEnabled="{Binding ElementName=toolTipController, Path=IsChecked}" />

问题根源

  1. 依赖属性注册错误:注册EnabledToolTipProperty和DisabledToolTipProperty时,所有者类型错误地写为typeof(Field),而非自定义控件的typeof(ButtonDualToolTip),导致绑定无法正确解析属性值。
  2. Style触发器无默认值:初始加载时Style未设置ToolTip的默认值,仅通过DataTrigger触发状态切换,可能因初始化顺序问题导致启用状态的绑定未生效。
  3. 本地值优先级冲突:在依赖属性setter中直接设置ToolTip属于本地值,优先级高于Style中的触发器Setter,会覆盖状态切换效果。

修正方案

1. 修正依赖属性注册

将两个依赖属性的所有者类型改为typeof(ButtonDualToolTip),同时添加默认值避免空绑定:

public static readonly DependencyProperty EnabledToolTipProperty =
    DependencyProperty.Register(nameof(EnabledToolTip), typeof(string), typeof(ButtonDualToolTip), new PropertyMetadata(string.Empty));

public static readonly DependencyProperty DisabledToolTipProperty =
    DependencyProperty.Register(nameof(DisabledToolTip), typeof(string), typeof(ButtonDualToolTip), new PropertyMetadata(string.Empty));

2. 优化Style逻辑

在Style中设置ToolTip的默认绑定为EnabledToolTip,仅用一个Trigger处理禁用状态的切换,避免初始化时无值的问题:

<Button x:Class="ButtonDualToolTip"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        ToolTipService.ShowOnDisabled="True">
   <Button.Style>
      <Style TargetType="Button">
          <!-- 默认绑定启用状态的ToolTip -->
          <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=EnabledToolTip}" />
          <Style.Triggers>
              <Trigger Property="IsEnabled" Value="False">
                  <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=DisabledToolTip}" />
              </Trigger>
          </Style.Triggers>
      </Style>
   </Button.Style>
</Button>

3. 移除setter中的手动赋值

删除在EnabledToolTip和DisabledToolTip的setter中直接设置ToolTip的代码,确保Style触发器的优先级生效。

验证效果

使用示例代码测试:

  • 勾选CheckBox时,按钮启用,显示ToolTip为"enabled"
  • 取消勾选时,按钮禁用,显示ToolTip为"disabled"
  • 初始化加载时,按钮默认启用状态可直接显示正确的ToolTip,无需热重载触发

内容的提问来源于stack exchange,提问作者Synck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:13:17