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

发布于 2024-11-28 12:52:58 字数 92 浏览 2 评论 0原文

是否可以关闭所有控件的工具提示(始终或基于某些规则),而无需在每个控件上设置 TooltipService.IsEnabled?我的意思是,检查所有逻辑项目需要太多时间。

Is it possible to turn-off toooltips for all controls (always or based on some rule) without setting TooltipService.IsEnabled on each control? I mean, going through all logical items takes too much time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夜血缘 2024-12-05 12:52:58

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

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

Try this. It hides all tooltips.

<Style TargetType="{x:Type ToolTip}">
    <Setter Property="Visibility"
            Value="Collapsed" />
</Style>
孤单情人 2024-12-05 12:52:58

您应该能够使用多种方法来完成此任务。 Marco Zhou 在 此发布。,这两种方法都依赖于将父控件(例如 窗户。显然它会继承给所有子项,因此您可以将其设置在那里以禁用所有工具提示。

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

编辑

添加代码以使其更易于理解:

创建 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);
    }
}

There are several ways you should be able to use to accomplish this. Marco Zhou outlines two of them in this posting., both of these methods relying on setting TooltipService.IsEnabled to False for a parent control such as a Window. Apparently it inherits to all children, so you can set it just there to disable all tooltips.

You could also set all of your Tooltips to a style which had bindings to a property that would make them invisible or disabled when you wanted.

EDIT

Adding the Code to make it easier to understand:

Create the ToolTipEnabled Attached Property which sets the FrameworkPropertyMetadataOptions.Inherits so that it will be inherited by the children.

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);
            }
        }));
}

You can either use this property in the XAML or codebehind as below:

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

Or

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

        // You can programmatically disable tool tip here.
        this.SetValue(ToolTipBehavior.ToolTipEnabledProperty, false);
    }
}
飘逸的'云 2024-12-05 12:52:58

将此样式放在整个应用程序中可访问的位置(资源字典或 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>

Put this style where it is accessible throughout the application(a resourcedictionary or App.xaml) so you won't need to reference this style in any textbox.

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

NOTE
This is the default textbox style generated by Expression blend to which I have added the following trigger which enables tooltips when textbox is not empty and disables them otherwise

<Trigger Property="Text" Value="">
                            <Setter Property="ToolTipService.IsEnabled" Value="False"/>
                        </Trigger>
暖心男生 2024-12-05 12:52:58

我不知道任何全局设置,但有一种简单的方法可以使用 Linq-to-VisualTree,我不久前编写的实用程序,为可视化树提供 Linq-to-XML 风格的 API 。

以下应该可以解决问题:

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

I don't know of any global setting, but there is an easy way to 'visit' all of the elements of your visual tree using Linq-to-VisualTree, I utility I wrote a while back that providers a Linq-to-XML style API for the visual tree.

The following should do the trick:

foreach(var element in window.Descendants())
  ToolttipService.SetIsEnabled(element, false);
×纯※雪 2024-12-05 12:52:58

您可以尝试使用

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

You can try to use

ToolTipService.IsOpenProperty.OverrideMetadata(typeof(DependencyObject),new PropertyMetadata(false));
高冷爸爸 2024-12-05 12:52:58

我没有在一个语句中处理整个应用程序的答案,但我已经能够将许多特定于 UI 的参数集中在一个通用基类中,然后创建从该基类派生的应用程序并继承集中设置。我应该提到,您必须添加一些额外的管道到基类中以支持 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.IsEnabledToolTipService.ShowDuration

您可以看到,如果 MyToolTipDuration 设置为零,MyToolTipEnabled 将返回 false,这会禁用工具提示。在我的第一次尝试中,我尝试简单地将 MyToolTipDuration 设置为零,而不将 ToolTipService.IsEnabled=MyToolTipEnabled 属性结合使用,但所有这些都完成了闪烁的、几乎难以阅读的工具提示时隐时现。

总的来说,这对我来说效果很好(ymmv),尽管不如单个设置或单个调用来处理整个应用程序,并避免使用我希望支持的功能的工具提示将这些绑定分发到每个项目中的需要禁用。哦,好吧,在罗马的时候……

无论如何,希望有人发现这个有用。

I don't have an answer for handling the entire app in one statement, but I've been able to centralize a number of UI-specific parameters in a general base class, then create applications which are derived off this base class and inherit the centralized settings. I should mention there's some extra plumbing you have to add to the base class to support MVVM as in the following:

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));
        }
    }

The XAML code looks like this:

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

With the important bindings being those related to ToolTipService.IsEnabled and ToolTipService.ShowDuration.

You can see that if MyToolTipDuration is set to zero, MyToolTipEnabled will return false and this disables the tooltip. In my first attempt I tried simply setting MyToolTipDuration to zero without using the ToolTipService.IsEnabled= in conjunction with the MyToolTipEnabled property, but all that accomplished was flashing, barely-readable tooltips which appear and disappear.

Overall this worked pretty well for me (ymmv), though not as well as a single setting or single call that would have handled the entire app and circumvented the need for distributing these bindings into every item with a tooltip I wanted to be support the ability to disable. Oh well, when in Rome....

In any event, hopefully someone finds this of use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文