如何关闭整个应用程序的工具提示

时间:2011-08-08 06:25:06

标签: wpf tooltip

是否可以关闭所有控件的toooltips(总是或基于某些规则),而无需在每个控件上设置TooltipService.IsEnabled?我的意思是,经历所有逻辑项目需要花费太多时间。

6 个答案:

答案 0 :(得分:4)

您应该有几种方法可以用来完成此任务。 Marco Zhou在this posting.中概述了其中两个,这两种方法都依赖于为父控件(如Window)设置TooltipService.IsEnabled为False。显然它继承给所有孩子,所以你可以在那里设置它来禁用所有工具提示。

您还可以将所有工具提示设置为绑定到属性的样式,以便在需要时使其不可见或禁用。

修改

添加代码以便于理解:

创建ToolTipEnabled附加属性,该属性设置FrameworkPropertyMetadataOptions.Inherits,以便子项继承它。

public class ToolTipBehavior
{
    public static Boolean GetIsToolTipEnabled(FrameworkElement obj)
    {
        return (Boolean)obj.GetValue(ToolTipEnabledProperty);
    }

    public static void SetToolTipEnabled(FrameworkElement obj, Boolean value)
    {
        obj.SetValue(ToolTipEnabledProperty, value);
    }

    public static readonly DependencyProperty ToolTipEnabledProperty = DependencyProperty.RegisterAttached(
        "IsToolTipEnabled",
        typeof(Boolean),
        typeof(ToolTipBehavior),
        new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits, (sender, e) => 
        {
            FrameworkElement element = sender as FrameworkElement;
            if (element != null)
            {
                element.SetValue(ToolTipService.IsEnabledProperty, e.NewValue);
            }
        }));
}

您可以在XAML或代码隐藏中使用此属性,如下所示:

<Window x:Class="AnswerHarness.ToggleToolTipsDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cc="clr-namespace:AnswerHarness"
    Title="ToggleToolTipsDemo" Height="300" Width="300" Name="window">
  <StackPanel>
    <CheckBox IsChecked="{Binding Path=(cc:ToolTipBehavior.IsToolTipEnabled), ElementName=window}" Content="Enable ToolTip"/>
    <Border BorderBrush="Green" BorderThickness="1" Background="Yellow" ToolTip="Border">
      <StackPanel>
        <Button Width="120" Height="30" Content="Button1" ToolTip="Button1"/>
        <Button Width="120" Height="30" Content="Button2" ToolTip="Button2"/>
        <Button Width="120" Height="30" Content="Button3" ToolTip="Button3"/>
      </StackPanel>
    </Border>
  </StackPanel>
</Window>

或者

public partial class ToggleToolTipsDemo : Window
{
    public ToggleToolTipsDemo()
    {
        InitializeComponent();

        // You can programmatically disable tool tip here.
        this.SetValue(ToolTipBehavior.ToolTipEnabledProperty, false);
    }
}

答案 1 :(得分:2)

试试这个。它隐藏了所有工具提示。

<Style TargetType="{x:Type ToolTip}">
    <Setter Property="Visibility"
            Value="Collapsed" />
</Style>

答案 2 :(得分:1)

我不知道任何全局设置,但是有一种简单的方法可以使用Linq-to-VisualTree“访问”可视树的所有元素,我在一段时间后写了一些提供Linq-的实用程序可视化树的to-XML样式API。

以下应该可以解决问题:

foreach(var element in window.Descendants())
  ToolttipService.SetIsEnabled(element, false);

答案 3 :(得分:1)

将此样式放在整个应用程序可访问的位置(resourcedictionary或App.xaml),这样您就不需要在任何文本框中引用此样式。

<Style BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="AllowDrop" Value="true"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" ToolTipService.IsEnabled="False" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
                        <ScrollViewer ToolTipService.IsEnabled="False" x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Microsoft_Windows_Themes:ListBoxChrome>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                        <Trigger Property="Text" Value="">
                            <Setter Property="ToolTipService.IsEnabled" Value="False"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

注意 这是Expression blend生成的默认文本框样式,我添加了以下触发器,当文本框不为空时启用工具提示并禁用它们

<Trigger Property="Text" Value="">
                            <Setter Property="ToolTipService.IsEnabled" Value="False"/>
                        </Trigger>

答案 4 :(得分:0)

您可以尝试使用

ToolTipService.IsOpenProperty.OverrideMetadata(typeof(DependencyObject),new PropertyMetadata(false));

答案 5 :(得分:0)

我没有在一个声明中处理整个应用程序的答案,但我已经能够在一般基类中集中一些特定于UI的参数,然后创建派生的应用程序关闭此基类并继承集中设置。我应该提到一些额外的 plumbing 你必须添加到基类以支持MVVM,如下所示:

public class MyMainWindowBaseClass : Window, INotifyPropertyChanged
{
    ...whatever unrelated stuff you need in your class here...

    private int m_toolTipDuration = 3000;   // Default to 3 seconds

    public int MyToolTipDuration
    {
        get { return m_toolTipDuration; }
        set
        {
            if (m_toolTipDuration != value)
            {
                bool transition = (value == 0 || m_toolTipDuration == 0);

                m_toolTipDuration = value;
                NotifyPropertyChanged("MyToolTipDuration");

                if (transition)
                {
                    NotifyPropertyChanged("MyToolTipEnabled");
                }
            }
        }
    }
    public bool MyToolTipEnabled
    {
        get { return (m_toolTipDuration > 0);  }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    ... whatever variables, properties, methods, etc., you need here...

    ///-----------------------------------------------------------------------------
    /// <summary>
    /// Fires property-changed event notification
    /// </summary>
    /// <param name="propertyName">The name of the property that changed</param>
    ///-----------------------------------------------------------------------------
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

XAML代码如下所示:

    <Button Command="{Binding StartCommand}"
            Content="Start"
            FontWeight="Bold"
            Height="Auto"
            HorizontalAlignment="Left"
            Margin="20,40,0,0"
            Name="ui_StartButton"
            ToolTip="Click this button to begin processing."
            ToolTipService.IsEnabled="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=MyToolTipEnabled}"
            ToolTipService.ShowDuration="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=MyToolTipDuration}"
            VerticalAlignment="Top"
            Width="90"/>

重要的绑定与 ToolTipService.IsEnabled ToolTipService.ShowDuration 相关。

您可以看到,如果 MyToolTipDuration 设置为零, MyToolTipEnabled 将返回false,这会禁用工具提示。在我的第一次尝试中,我尝试将 MyToolTipDuration 设置为零,而不将 ToolTipService.IsEnabled = MyToolTipEnabled 属性结合使用,但所有已完成闪烁,几乎看不见的工具提示出现和消失。

总的来说,这对我来说非常好(ymmv),虽然不如单个设置或单个调用可以处理整个应用程序并且避免了使用工具提示将这些绑定分发到每个项目的需要我想要成为支持禁用功能。哦,在罗马的时候......

无论如何,希望有人发现这一点。