Отображение всплывающей подсказки на несфокусированном ToolStripItem - PullRequest
8 голосов
/ 27 сентября 2008

ToolStripItems показывают активное выделение при наведении на них курсора, даже если форма, в которой они находятся, не в фокусе. Однако они не показывают свои всплывающие подсказки, если только форма не сфокусирована. Я видел взлом ToolStrip "хотя-бы" . Кто-нибудь знает, как заставить ToolStripButton показывать всплывающую подсказку, когда его родительская форма не в фокусе?

Спасибо!

Ответы [ 4 ]

5 голосов
/ 04 октября 2008

Проблема в том, что 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);
    } 
}
2 голосов
/ 20 января 2012

Я попробовал несколько вещей и нашел, что это самое простое

когда я создавал элементы toolstripbutton, я добавлял обработчик события в событие hover:

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

это работает очень хорошо, хотя я замечаю небольшую начальную задержку, когда вы в первый раз наводите указатель мыши на панели инструментов

2 голосов
/ 28 сентября 2008

Возможно, один из двух подходов в этом коде уведет вас в правильном направлении ...

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, и всплывающая подсказка не будет отображаться, если вы не находитесь над полосой, но не над кнопкой.

Проблема со вторым (закомментированным способом) в том, что он вообще не отображается. Не совсем уверен, почему, но, возможно, вы можете отладить его.

1 голос
/ 21 ноября 2008

Я пытался сделать то же самое и решил, что это будет довольно сложно и не стоит. Причина заключается в том, что внутренне код .NET специально предназначен для показа всплывающей подсказки только в том случае, если окно активно - они проверяют это на уровне Win32, поэтому будет сложно выдумать код.

Вот фрагмент кода в ToolTip.cs, который проверяет «GetActiveWindow ()» и возвращает false. Вы можете увидеть комментарий в коде «Подсказки должны отображаться только в активной Windows».

Кстати, вы можете увидеть весь исходный код .NET BCL с Visual Studio 2008, вот инструкции, которые я использовал:

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