Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the ToolTip InitialShowDelay Property Globally

Tags:

c#

wpf

tooltip

xaml

I have an application that has upwards of a hundred different ToolTips set on a Ribbon control. All of the ToolTips pop up rather quickly (about half a second), and I would like to increase the pop up delay. After some research it appears the only way to do this in WPF is through the ToolTipService.InitialShowDelay property.

My question is, do I have to go through the XAML and explicitly say

ToolTipService.InitialShowDelay="2000"

For every single control that has a ToolTip? Or is there some way to set this property globally, using something like a Style?

Thanks for any ideas.

like image 380
Charlie Avatar asked Jun 04 '09 20:06

Charlie


4 Answers

Unfortunately, there's no easy way to do this. Ideally, you'd set ToolTipService.InitialShowDelay on FrameworkElement and let it propagate from there, but it turns out that doesn't seem to work.

Instead, you can set it on each type of control you want to set it on, for instance:

<Style TargetType="RibbonButton">     <Setter Property="ToolTipService.InitialShowDelay" Value="2000"/> </Style> <Style TargetType="RibbonToggleButton">     <Setter Property="ToolTipService.InitialShowDelay" Value="2000"/> </Style> <Style TargetType="RibbonDropDownButton">     <Setter Property="ToolTipService.InitialShowDelay" Value="2000"/> </Style> 

etc.

Although this is a pretty verbose way of doing it, at least you only have to set it on each type of control and not every control itself - and if you're using it in the Ribbon, then there's only a handful of controls to begin with.

To save yourself some hassle should you ever want to change the value, you may want to architect the above code using a resource value:

<sys:Int32 x:Key="ToolTipInitialShowDelay">2000</sys:Int32> <Style TargetType="RibbonButton">     <Setter Property="ToolTipService.InitialShowDelay"              Value="{StaticResource ToolTipInitialShowDelay}"/> </Style> <Style TargetType="RibbonToggleButton">     <Setter Property="ToolTipService.InitialShowDelay"              Value="{StaticResource ToolTipInitialShowDelay}"/> </Style> <Style TargetType="RibbonDropDownButton">     <Setter Property="ToolTipService.InitialShowDelay"              Value="{StaticResource ToolTipInitialShowDelay}"/> </Style> 

Alternatively, if you are not already using BasedOn styles, you could shorten it to:

<Style x:Key="ToolTipDefaults">     <Setter Property="ToolTipService.InitialShowDelay" Value="2000"/> </Style> <Style TargetType="RibbonButton" BasedOn="{StaticResource ToolTipDefaults}"/> <Style TargetType="RibbonToggleButton" BasedOn="{StaticResource ToolTipDefaults}"/> <Style TargetType="RibbonDropDownButton" BasedOn="{StaticResource ToolTipDefaults}"/> 

The limitation to this approach being that a style can only be based on one parent style, so if you're already using this pattern, you won't be able to do this.

like image 57
Nicholas Armstrong Avatar answered Sep 18 '22 13:09

Nicholas Armstrong


I've run into the same problem and achieved an appreciable solution. Two of them, actually.

Both of them are based on DependencyProperty metadata system. For both of them you will need some pretty similar static-initialization code:

public static class ToolTipServiceHelper {     static ToolTipServiceHelper()     {         ToolTipService.InitialShowDelayProperty             .OverrideMetadata(typeof(FrameworkElement),                                new FrameworkPropertyMetadata(...));     } } 

What goes instead of "..."?

First solution is pretty obvious: place there the desired default value which will apply to the entire application except places where an actual value is provided.

The second solution is the tricky one: instead of "..." you provide default value from default metadata, but aside from that you change the options, actually you have to make the property inheritable.

new FrameworkPropertyMetadata(     ToolTipService.InitialShowDelayProperty.DefaultMetadata.DefaultValue,     FrameworkPropertyMetadataOptions.Inherits) 

When the property is inheritable you can make things like this:

<Window xmlns="..."         ...         ToolTipService.InitialShowDelay="2000">     ... </Window> 

That will do the trick for the entire window or any other element you apply the property to.

HTH

like image 20
archimed7592 Avatar answered Sep 20 '22 13:09

archimed7592


I like the solution of archimed7592 but it will not run by itself. You need to use class somehow to run it's static constructor. So I've choose to place this code into static constructor of my application Application class like this:

    static NetFriendApplication()
    {
        ToolTipService.ShowDurationProperty.OverrideMetadata(
            typeof (FrameworkElement), new FrameworkPropertyMetadata(int.MaxValue));
    }

And in my case I need to set another property but idea is the same. So don't be curious.

like image 35
Mike Eshva Avatar answered Sep 18 '22 13:09

Mike Eshva


The solution of Nicholas Armstrong is very good, but styling a FrameworkElement works if you set the ToolTipService.IsEnabled to true.

In my project I have a commom style for every field and setting the ToolTip.InitialDelay there was the reasonable thing to do and it didn't work, so I gave it a try to the ToolTip.IsEnabled and it worked.

Example below:

<Style x:Key="FieldStyle" TargetType="FrameworkElement">
    <Setter Property="ToolTipService.ShowOnDisabled" Value="True"/>
    <Setter Property="ToolTipService.ShowDuration" Value="20000"/>
    <Setter Property="ToolTipService.InitialShowDelay" Value="3000"/>
    <Setter Property="ToolTipService.IsEnabled" Value="True"/>
</Style>
like image 37
maykonvs Avatar answered Sep 21 '22 13:09

maykonvs