Showing a tooltip on a non-focused ToolStripItem

落花浮王杯 提交于 2019-12-05 21:17:27

问题


ToolStripItems show Active highlighting when you mouse over them, even if the form they are in is not in focus. They do not, however, show their tooltips, unless the form is focused. I have seen the ToolStrip 'click-though' hack. Anyone know how to make a ToolStripButton show its tooltip when its parent form is not in focus?

Thanks!


回答1:


The problem is that the ToolStrip "controls" like ToolStripButton or ToolStripDropDownButton don't inherit from Control. For now I addressed the problem by focusing the ToolStrip whenever a user hovers over a button. The button's MouseHover event is fired too late -- after the "show tooltip" code would have been run, so I extended the ToolStripDropDownButton class and used my new button. This method should work for any of the other button-like classes inheriting from ToolStripItem

public class ToolStripDropDownEx : ToolStripDropDownButton
{
    public ToolStripDropDownEx(string text)
    {
    }

    protected override void OnMouseHover(EventArgs e)
    {
        if (this.Parent != null)
            Parent.Focus();
        base.OnMouseHover(e);
    } 
}



回答2:


Perhaps one of the two approaches in this code will kick you off in the right direction...

public Form1()
{
    InitializeComponent();

    tooltip = new ToolTip();
    tooltip.ShowAlways = true;
}

private ToolTip tooltip;
private void toolStripButton_MouseHover(object sender, EventArgs e)
{
    if (!this.Focused)
    {
        ToolStripItem tsi = (ToolStripItem)sender;
        tooltip.SetToolTip(toolStrip1, tsi.AutoToolTip ? tsi.ToolTipText : tsi.Text);
        /*tooltip.Show(tsi.AutoToolTip ? tsi.ToolTipText : tsi.Text, this, 
            new Point(toolStrip1.Left, toolStrip1.Bottom));*/
    }
}

private void toolStripButton_MouseLeave(object sender, EventArgs e)
{
    tooltip.RemoveAll();
}

The problem with the first is you can't set it to the button directly, it doesn't inherit from Control, and the tooltip won't show up unless you're over the strip but not over a button.

The problem with the second (commented out way) is it doesn't display at all. Not quite sure why, but maybe you can debug it out.




回答3:


i tried a few things and found this to be the simplest

when i create the toolstripbutton items i added an event handler to its hover event:

private sub SomeCodeSnippet()

    Me.tooltipMain.ShowAlways = True

    Dim tsi As New ToolStripButton(String.Empty, myImage)
    tsi.ToolTipText = "my tool tip text"
    toolstripMain.Add(tsi)

    AddHandler tsi.MouseHover, AddressOf ToolStripItem_MouseHover

end sub

then the event handler:

Private Sub ToolStripItem_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf sender Is ToolStripButton Then
        Me.tooltipMain.SetToolTip(Me.toolstripMain, CType(sender, ToolStripButton).ToolTipText)
    End If

End Sub

this works really nicely, although i do notice a tiny initial delay when you hover over the toolstrip for the 1st time




回答4:


I was trying to do the same thing and determined it was going to be pretty challenging and not worth it. The reason is that internally, the .NET code is specifically designed to only show the tooltip if the window is active - they are checking this at a Win32 level so its going to be hard to fake the code out.

Here is the code snippet in ToolTip.cs that checks "GetActiveWindow()" and returns false. You can see the comment in the code "ToolTips should be shown only on active Windows."

By the way, you can see all the source code for the .NET BCL with Visual Studio 2008, here are the instructions I used:

http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx

// refer VsWhidbey 498263: ToolTips should be shown only on active Windows.
private bool IsWindowActive(IWin32Window window)
{ 
    Control windowControl = window as Control;
    // We want to enter in the IF block only if ShowParams does not return SW_SHOWNOACTIVATE. 
    // for ToolStripDropDown ShowParams returns SW_SHOWNOACTIVATE, in which case we DONT want to check IsWindowActive and hence return true. 
    if ((windowControl.ShowParams & 0xF) != NativeMethods.SW_SHOWNOACTIVATE)
    { 
        IntPtr hWnd = UnsafeNativeMethods.GetActiveWindow();
        IntPtr rootHwnd =UnsafeNativeMethods.GetAncestor(new HandleRef(window, window.Handle), NativeMethods.GA_ROOT);
        if (hWnd != rootHwnd)
        { 
            TipInfo tt = (TipInfo)tools[windowControl];
            if (tt != null && (tt.TipType & TipInfo.Type.SemiAbsolute) != 0) 
            { 
                tools.Remove(windowControl);
                DestroyRegion(windowControl); 
            }
            return false;
        }
    } 
    return true;
} 


来源:https://stackoverflow.com/questions/143058/showing-a-tooltip-on-a-non-focused-toolstripitem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!