Сцена: A (маленькая) форма, в которой размещен UserControl.
График: Всякий раз, когда UserControl вызывает событие при наведении, отображать некоторую (графическую) информацию в виде всплывающей подсказки. Когда пользователь перемещает мышь, снова исчезает.
Примечания: Я хотел бы отобразить более одной «всплывающей подсказки», где каждая подсказка представляет собой UserControl, отображающий информацию в графической форме. Не просто текст в желтом поле! Также я использую библиотеку Windows.Forms.
Это то, что я имею до сих пор:
private void myControl_Hovered(object sender, MyEventArgs e)
{
var tooltip = new MyToolTip();
Controls.Add(tooltip);
tooltip.UpdateDisplay(e.Data);
tooltip.Show();
}
Но он появляется на заднем плане (я могу справиться с этим) и, к сожалению, ограничивается окном ...
РЕДАКТИРОВАТЬ: Вот что я закончил делать ...
Я не смог заставить работать ToolTip
элемент управления, поставляемый с .NET. Это происходит главным образом потому, что я пытаюсь показать всплывающие подсказки для «горячих точек» в нарисованном пользователем элементе управления (подумайте о графике функциональных точек, покажите дополнительные элементы для точек). Элемент управления ToolTip действительно хотел бы показывать только тогда, когда пользователь впервые вводит элемент управления - показ вручную, что он не работает. Я старался. Долго и трудно.
Итак, этот класс ToolTipWindow
можно использовать для отображения элемента управления в безрамном окне. Я добавил свойство Offset
, чтобы оно могло отображаться со смещением относительно текущей позиции мыши.
/// <summary>
/// A tooltip class to display some information from a control.
/// </summary>
internal class ToolTipWindow: Form
{
/// <summary>
/// The offset from the mouse pointer to show the window at.
/// </summary>
public Point Offset { get; set;}
internal ToolTipWindow(Control controlToDisplay)
{
FormBorderStyle = FormBorderStyle.None;
TopMost = true;
ShowInTaskbar = false;
Opacity = 0.9;
Width = controlToDisplay.Width;
Height = controlToDisplay.Height;
Controls.Add(controlToDisplay);
controlToDisplay.Show();
}
/// <summary>
/// Move the window to an offset of mouse pointer.
/// </summary>
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
Location = new Point(MousePosition.X + Offset.X, MousePosition.Y + Offset.Y);
}
/// <summary>
/// Move the window to an offset of mouse pointer.
/// </summary>
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible)
{
Location = new Point(MousePosition.X + Offset.X, MousePosition.Y + Offset.Y);
}
}
}
Чтобы показать подсказку, вы можете перехватить события MouseHover
и MouseMove
. Сначала проверьте, если вы находитесь выше «горячей точки» и покажите всплывающую подсказку. В MouseMove
скрывайте всплывающие подсказки, если вы не находитесь над «горячей точкой». Кроме того, при закрытии окна обязательно закройте все окна всплывающих подсказок!
Примечание: Событие MouseHover
будет отображаться только при первом входе мыши в элемент управления. Если вы хотите, чтобы он появлялся повторно (как в случае обнаружения «горячих точек»), вам необходимо добавить код, подобный следующему, в элемент управления, содержащий «горячие точки»:
#region AddReHoverExperience
// ReSharper disable InconsistentNaming
// found this code here: http://www.pinvoke.net/default.aspx/user32.TrackMouseEvent
[DllImport("user32.dll")]
static extern int TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
[StructLayout(LayoutKind.Sequential)]
public struct TRACKMOUSEEVENT
{
public UInt32 cbSize;
public UInt32 dwFlags;
public IntPtr hwndTrack;
public UInt32 dwHoverTime;
}
TRACKMOUSEEVENT tme;
private const uint TME_HOVER = 0x1;
protected override void OnMouseHover(EventArgs e)
{
base.OnMouseHover(e);
OnMouseEnter(e);
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
tme = new TRACKMOUSEEVENT
{
hwndTrack = Handle,
dwFlags = TME_HOVER,
dwHoverTime = 500
};
tme.cbSize = (uint)Marshal.SizeOf(tme);
TrackMouseEvent(ref tme);
}
// ReSharper restore InconsistentNaming
#endregion AddReHoverExperience