Krzysztof Adamowicz
Krzysztof Adamowicz

Reputation: 41

Change delay time ToolTipText on ToolStripButton

Application is in c#/WinForm I'm using ToolStrip with button.

I setted ToolTipText, it is working.

Can I change the delay time to longer value ?

In other controls I'm using ToolTip control and it is possible (AutoPopDelay value).

Upvotes: 3

Views: 489

Answers (3)

Reza Aghaei
Reza Aghaei

Reputation: 125197

In my other answer, I've showed how you can modify the initial delay, but as pointed out by Elmue in the comments, it looks like OP is looking for AutoPopDelay which is the duration of showing the tooltip.

To do so, you can get the internal ToolTip of ToolStrip and set its properties:

private void Form1_Load(object sender, EventArgs e)
{
    var toolTip = (ToolTip)this.toolStrip1.GetType()
        .GetProperty("ToolTip",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance).GetValue(toolStrip1);
    toolTip.AutoPopDelay = 10000;
}

Upvotes: 3

Reza Aghaei
Reza Aghaei

Reputation: 125197

Here's a totally different approach that you should almost always avoid, unless you know you are changing a system-wide setting which doesn't affect just your application.

As I mentioned in the other answer, there's an internal timer responsible for the hover time to shows the tooltip and the default interval for the timer is the value of SystemInformation.MouseHoverTime.

You can change the value using SystemParametersInfo. This value is a system-wide setting, and if you change it, it will be applied to all applications which rely on this value. That said, you decide whether you want to change it or not, but here is the solution:

Assuming you create the following helper class:

using System.Runtime.InteropServices;
public static class SystemInformationExtensions
{
    private const int SPI_SETMOUSEHOVERTIME = 0x0067;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern bool SystemParametersInfo(
        int nAction, int nParam, ref int value, int ignore);
    public static void SetMouseHoverTime(int milliseconds)
    {
        SystemParametersInfo(SPI_SETMOUSEHOVERTIME,
            milliseconds, ref milliseconds,0);
    }
}

Then you can use it like this:

private void TestForm_Load(object sender, EventArgs e)
{
    SystemInformationExtensions.SetMouseHoverTime(3000);
}

Upvotes: 1

Reza Aghaei
Reza Aghaei

Reputation: 125197

It's possible, but not as straightforward as you would expect.

The ToolStrip control doesn't expose a ToolTip property while it has an internal ToolTip property. In addition, the control doesn't rely on the automatic tooltip behavior and manually shows the tooltip on a Hover event. And the problem here, is hover event is also has a custom implementation relying on an internal timer.

Considering above facts, you can imagine how hacky is the solution to change the tooltip delay for toolstrip, and you decide whether it's worth it or not, but here is the solution:

private void TestForm_Load(object sender, EventArgs e)
{
    var mouseHoverTimerProperty =
        toolStrip1.GetType().GetProperty("MouseHoverTimer",
        BindingFlags.NonPublic | BindingFlags.Instance)
        .GetValue(toolStrip1);
    var mouseHoverTimerField =(System.Windows.Forms.Timer)
        (mouseHoverTimerProperty.GetType().GetFields(
        BindingFlags.NonPublic | BindingFlags.Instance)
        .Where(x => x.FieldType == typeof(System.Windows.Forms.Timer)).First()
        .GetValue(mouseHoverTimerProperty));

    mouseHoverTimerField.Interval = 3000;
}

Note: The reason that you see I've found the private field using its type but not its name, is because the name of the field in ".NET Framework" implementation is "mouseHoverTimer", and in the ".NET (CORE/5/6)" is "_mouseHoverTimer". That's is the problem when we rely on internal implementation details, but sometimes it's inevitable.

Upvotes: 1

Related Questions