Lonli-Lokli
Lonli-Lokli

Reputation: 3766

How turn-off tooltips for the whole application

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.

Upvotes: 3

Views: 4437

Answers (6)

Ed Bayiates
Ed Bayiates

Reputation: 11210

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

Upvotes: 4

John
John

Reputation: 352

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.

Upvotes: 0

MrSky
MrSky

Reputation: 41

Try this. It hides all tooltips.

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

Upvotes: 4

Alex
Alex

Reputation: 910

You can try to use

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

Upvotes: 0

Zahid Sattar
Zahid Sattar

Reputation: 1517

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>

Upvotes: 1

ColinE
ColinE

Reputation: 70122

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

Upvotes: 1

Related Questions