在非焦点 ToolStripItem 上显示工具提示

发布于 2024-07-07 00:54:29 字数 284 浏览 10 评论 0原文

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

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

—━☆沉默づ 2024-07-14 00:54:29

问题在于 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);
    } 
}

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);
    } 
}
轻许诺言 2024-07-14 00:54:29

也许此代码中的两种方法之一会引导您朝正确的方向前进...

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,并且工具提示不会'除非您越过条带但未越过按钮,否则不会出现。

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

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.

生寂 2024-07-14 00:54:29

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

当我创建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

这工作得很好,尽管我确实注意到当您将鼠标悬停在上面时有一个微小的初始延迟第一次使用工具条

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

街角卖回忆 2024-07-14 00:54:29

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

以下是 ToolTip.cs 中检查“GetActiveWindow()”并返回 false 的代码片段。 您可以看到代码中的注释“ToolTips should be displayed only on active Windows”。

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

http://blogs.msdn.com/sburke/archive/2008/01/16/配置-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;
} 

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;
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文