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





Возможно, один из двух подходов в этом коде подтолкнет вас в правильном направлении ...
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, и всплывающая подсказка не будет отображаться, если вы не находитесь над полосой, но не над кнопкой.
Проблема со вторым (закомментированным) способом в том, что он вообще не отображается. Не совсем уверен, почему, но, возможно, вы сможете отладить это.
Проблема в том, что «элементы управления» 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);
}
}
Я пытался сделать то же самое и решил, что это будет довольно сложно и того не стоит. Причина в том, что внутренне код .NET специально разработан для отображения всплывающей подсказки только в том случае, если окно активно - они проверяют это на уровне Win32, поэтому подделать код будет сложно.
Вот фрагмент кода в ToolTip.cs, который проверяет «GetActiveWindow ()» и возвращает false. Вы можете увидеть комментарий в коде «Всплывающие подсказки должны отображаться только в активной Windows».
Кстати, вы можете увидеть весь исходный код .NET BCL с Visual Studio 2008, вот инструкции, которые я использовал:
// 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;
}
я попробовал несколько вещей и обнаружил, что это самый простой
когда я создаю элементы 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
это работает очень хорошо, хотя я заметил небольшую начальную задержку, когда вы наводите курсор на панель инструментов в первый раз
почему ты хочешь сделать это? Ошибка скорее в активном отслеживании, когда форма не сфокусирована.