在非聚焦的ToolStripItem上显示工具提示

时间:2008-09-27 05:22:13

标签: c# .net winforms tooltip toolstrip

ToolStripItems在鼠标悬停时显示活动突出显示,即使它们所在的表单不在焦点上。但是,除非表格是重点,否则他们不会显示他们的工具提示。我见过ToolStrip 'click-though' hack。有人知道如何让ToolStripButton在其父窗体未对焦时显示其工具提示吗?

谢谢!

4 个答案:

答案 0 :(得分:5)

问题是ToolStrip“控件”如ToolStripButton或ToolStripDropDownButton不会从Control继承。现在,只要用户将鼠标悬停在按钮上,就可以通过聚焦ToolStrip解决问题。按钮的MouseHover事件被触发太晚了 - 在运行“show tooltip”代码之后,我扩展了ToolStripDropDownButton类并使用了我的新按钮。此方法适用于继承自ToolStripItem

的任何其他类按钮的类
public class ToolStripDropDownEx : ToolStripDropDownButton
{
    public ToolStripDropDownEx(string text)
    {
    }

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

答案 1 :(得分:2)

这个代码中的两种方法中的一种可能会让你朝着正确的方向前进......

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

第一个问题是你不能直接将它设置为按钮,它不会从Control继承,并且工具提示不会显示,除非你已经超过了条带而不是按钮。< / p>

第二个问题(注释掉的方式)是根本不显示。不太清楚为什么,但也许你可以调试它。

答案 2 :(得分:2)

我尝试了一些事情,发现这是最简单的

当我创建toolstripbutton项时,我为其悬停事件添加了一个事件处理程序:

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

然后是事件处理程序:

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

这非常好用,但是当你第一次将鼠标悬停在工具条上时我注意到了一个微小的初始延迟

答案 3 :(得分:1)

我试图做同样的事情,并确定它将是非常具有挑战性的,不值得。原因在于,在内部,.NET代码专门设计为仅在窗口处于活动状态时显示工具提示 - 他们在Win32级别检查这一点,因此很难伪造代码。

以下是ToolTip.cs中的代码片段,用于检查“GetActiveWindow()”并返回false。您可以在代码“工具提示应仅在活动Windows上显示”中看到注释。

顺便说一句,您可以使用Visual Studio 2008查看.NET BCL的所有源代码,以下是我使用的说明:

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