3

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.

4
  • Why would you want to do that? Commented Aug 8, 2011 at 6:31
  • We dont want to show tooltips for empty cells textboxes, etc. So we need to specify common converter for Tooltip service for all controls. Maybe there is a more common way than specifying this converter for each control. Commented Aug 8, 2011 at 6:41
  • What about making the converter return null in cases where there is nothing to show? That should in effect disable the tooltip. Commented Aug 8, 2011 at 6:44
  • Yes, and that's what I want - to set a converter. But as I know (and want to be wrong) I have to specify this converter for the all application controls. Commented Aug 8, 2011 at 6:54

6 Answers 6

4

Try this. It hides all tooltips.

<Style TargetType="{x:Type ToolTip}">
    <Setter Property="Visibility"
            Value="Collapsed" />
</Style>
Sign up to request clarification or add additional context in comments.

1 Comment

Best answer imo
4

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

Comments

1

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>

3 Comments

I have tooltips not only for textboxes, you mean I should edit all templates for all controls with tooltips?
you were saying that "We don't want to show tooltips for empty cells textboxes". This is the way to do it if that's the case. You don't need to edit any template. You just need to add this where it is accessible to all your textboxes and it will be applied automatically. This style only applies to textboxes since TargetType="{x:Type TextBox}"
I've accepted your answer, although it's not completele mine.
1

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

2 Comments

As I wrote in question, it takes too much time.
Sorry - I thought your meant it took too much time to write the code manually to set this value on all your elements;-)
0

You can try to use

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.