如何在Windows.Forms中进行浮动(工具提示)控件?

Dar*_*mas 3 .net c# tooltip winforms

场景:托管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();
}
Run Code Online (Sandbox Code Playgroud)

但它出现在后台(我可以处理),遗憾的是,仅限于窗口......


编辑:这是我最终做的...

我无法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);    
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要显示工具提示,您可以捕获MouseHoverMouseMove事件.如果您位于"热点"之上并显示工具提示,请先检查.在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
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 5

您的代码存在严重问题,每次鼠标悬停时都会向用户控件添加控件但从不删除它们.

首先,请确保内置的ToolTip组件尚未解决您的问题.应该,它的行为与你描述的方式相同.请注意,它具有OwnerDraw属性,它允许您自定义其外观.

创建你自己很棘手.工具提示是一个相当不寻常的窗口,它不像所有其他WF控件那样是子控件.它是一个顶级窗口,允许它与其他窗口重叠并延伸到容器窗口的客户区域之外.Windows Forms中唯一以这种方式运行的类是Form类.可以使用无边框表单来实现自定义工具提示.

最棘手的部分是确保当用户控件的父窗体移动时它会移动.您必须迭代UC的Parent属性,直到找到Form,然后订阅LocationChanged,VisibleChanged和FormClosing事件.您还应该连接UC的ParentChanged和HandleDestroyed事件.

  • 双引号功能无法关闭. (3认同)