Отображение всплывающей подсказки для элемента ToolStripItem без фокуса

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

Спасибо!


person foson    schedule 27.09.2008    source источник
comment
почему ты хочешь сделать это? Ошибка скорее заключается в активном отслеживании, когда форма не сфокусирована.   -  person OregonGhost    schedule 27.09.2008
comment
@OregonGhost - я создал плавающую / всегда поверх панели инструментов и хотел, чтобы всплывающие подсказки отображались при наведении курсора, даже когда другие приложения были активны.   -  person foson    schedule 31.12.2008


Ответы (4)


Проблема в том, что «элементы управления» 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);
    } 
}
person foson    schedule 04.10.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();
}

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

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

person Matthew Scharley    schedule 28.09.2008

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

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

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

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

person KevinKode    schedule 19.01.2012

Я пытался сделать то же самое и решил, что это будет довольно сложно и не стоит того. Причина в том, что внутри код .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;
} 
person Maurice Flanagan    schedule 20.11.2008