8

当您将鼠标悬停在 ToolStripItems 上时,它们会显示活动突出显示,即使它们所在的表单不在焦点上也是如此。但是,除非表单获得焦点,否则它们不会显示工具提示。我见过ToolStrip 'click-though' hack。任何人都知道如何让 ToolStripButton 在其父窗体不在焦点时显示其工具提示?

谢谢!

4

4 回答 4

6

问题是 ToolStrip“控件”,如 ToolStripButton 或 ToolStripDropDownButton 不继承自 Control。现在我通过在用户将鼠标悬停在按钮上时聚焦 ToolStrip 来解决这个问题。按钮的 MouseHover 事件触发得太晚了——在“显示工具提示”代码运行之后,所以我扩展了 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);
    } 
}
于 2008-10-04T13:35:16.857 回答
3

也许这段代码中的两种方法之一会让你朝着正确的方向前进……

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 继承,并且工具提示不会显示,除非您在条上而不是在按钮上。

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

于 2008-09-28T08:29:14.637 回答
2

我尝试了一些东西,发现这是最简单的

当我创建工具条按钮项目时,我向其悬停事件添加了一个事件处理程序:

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

这非常有效,尽管当您第一次将鼠标悬停在工具条上时,我确实注意到了一个微小的初始延迟

于 2012-01-19T21:07:13.283 回答
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;
} 
于 2008-11-20T23:26:07.440 回答