如何使在Windows.Forms的浮动(提示)控制? [英] How to make a floating (tooltip) control in Windows.Forms?

查看:222
本文介绍了如何使在Windows.Forms的浮动(提示)控制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的场景:的A(短小)形式承载用户控件

情节:的每当用户控件提出了一个悬停事件,显示工具提示时尚一些(图形)的信息。当用户移动鼠标,再次淡化他们离开。

注:的我想显示多个工具提示,每个工具提示是在一个图形化的方式显示信息的用户控件。不只是在一个黄色框中的文字!另外,我使用的是Windows.Forms的库。

这是我到目前为止有:

 私人无效myControl_Hovered(对象发件人,MyEventArgs E)
{
    VAR提示=新MyToolTip();
    Controls.Add被(提示);
    tooltip.UpdateDisplay(e.Data);
    tooltip.Show();
}
 

但它显示了在后台(我可以搞定)和可悲的是,被限制在窗口...


编辑:这是我落得这样做......

我无法得到具备.NET上班工具提示控制。这主要是因为我想显示工具提示在用户绘制控件热点(想想功能点,显示其它项目的点积)。该工具提示控制真的很想当用户第一次进入控制,只显示 - 手动显示它似乎并没有工作。我试过了。漫长而艰难的。

所以,这个 ToolTipWindow 类可以用来显示一个无框窗的控制。我添加了一个偏移属性,因此它可以被显示在偏移到当前鼠标的位置。

  ///<总结>
///一个工具提示类来显示从控制的一些信息。
///< /总结>
内部类ToolTipWindow:表
{
    ///<总结>
    ///来自鼠标指针的偏移量,以显示在该窗口。
    ///< /总结>
    公共点偏移{获得;组;}

    内部ToolTipWindow(控制controlToDisplay)
    {
        FormBorderStyle = FormBorderStyle.None;
        最顶层=真;
        ShowInTaskbar = FALSE;
        不透明度= 0.9;
        宽度= controlToDisplay.Width;
        身高= controlToDisplay.Height;
        Controls.Add被(controlToDisplay);
        controlToDisplay.Show();
    }

    ///<总结>
    ///移动窗口到鼠标指针的偏移量。
    ///< /总结>
    保护覆盖无效OnShown(EventArgs的发送)
    {
        base.OnShown(E);
        位置=新的点(MousePosition.X + Offset.X,MousePosition.Y + Offset.Y);
    }

    ///<总结>
    ///移动窗口到鼠标指针的偏移量。
    ///< /总结>
    保护覆盖无效OnVisibleChanged(EventArgs的发送)
    {
        base.OnVisibleChanged(E);
        如果(可见)
        {
            位置=新的点(MousePosition.X + Offset.X,MousePosition.Y + Offset.Y);
        }
    }
}
 

要显示工具提示,您可以赶上 MouseHover 的MouseMove 事件。首先检查,如果你是一个以上的热点,并显示工具提示。在的MouseMove ,隐藏工具提示,如果你是不是上面一个热点。此外,在关闭该窗口,请确保同时关闭所有的工具提示窗口!

注意: MouseHover 事件只出现在第一时间鼠标进入控制。如果你想让它反复出现(如在检测热点的情况下),你应该添加code像下面包含了热点的控制:

 #地区AddReHoverExperience
    // ReSharper的禁用InconsistentNaming
    //发现这个code在这里:http://www.pinvoke.net/default.aspx/user32.TrackMouseEvent

    [的DllImport(user32.dll中)
    静态外部INT TrackMouseEvent(REF TRACKMOUSEEVENT lpEventTrack);
    [StructLayout(LayoutKind.Sequential)

    公共结构TRACKMOUSEEVENT

    {
        公共UInt32的CBSIZE;
        公共UInt32的dwFlags中;
        公众的IntPtr hwndTrack;
        公共UInt32的dwHoverTime;
    }

    TRACKMOUSEEVENT TME;
    私人常量UINT TME_HOVER =为0x1;

    保护覆盖无效OnMouseHover(EventArgs的发送)
    {
        base.OnMouseHover(E);
        OnMouseEnter在(E);
    }

    保护覆盖无效OnMouseEnter在(EventArgs的发送)
    {
        base.OnMouseEnter(E);
        TME =新TRACKMOUSEEVENT
                  {
                      hwndTrack =手柄,
                      dwFlags中= TME_HOVER,
                      dwHoverTime = 500
                  };
        tme.cbSize =(UINT)Marshal.SizeOf(TME);
        TrackMouseEvent(REF TME);
    }
    // ReSharper的恢复InconsistentNaming
    #endregion AddReHoverExperience
 

解决方案

您code有一个严重的问题,它增加了一个控制权交给用户控制每次鼠标悬停,但从来没有将其删除。

首先,非常肯定地说内置的工具提示组件已经不解决您的问题。它应该,它的行为的描述方式。需要注意的是它具有OwnerDraw属性,它可以让你自定义其外观。

创建自己的是棘手的。工具提示是一个相当不寻常的窗口,它不是像所有其他WF控件的子控件。它是一个顶层窗口,这使得它能够重叠其它窗口并延伸超过容器窗口的客户区。在Windows窗体的行为这种方式唯一的类是Form类。使用一个无国界的形式来实现自定义的工具提示是可能的。

最棘手的部分是确保移动时的用户控件移动父窗体。你必须遍历UC的Parent属性,直到找到一个表格,然后订阅LocationChanged,VisibleChanged在和的FormClosing事件。您还应该接线UC的ParentChanged和HandleDestroyed事件。

The Scene: A (smallish) Form hosting a UserControl.

The Plot: Whenever UserControl raises a hover event, display some (graphical) information in a tool tip fashion. When the user moves the mouse, fade them away again.

Notes: I'd like to display more than one "tooltip", with each tooltip being a UserControl displaying information in a graphical manner. Not just text in a yellow box! Also, I'm using the Windows.Forms library.

This is what I have so far:

private void myControl_Hovered(object sender, MyEventArgs e)
{            
    var tooltip = new MyToolTip();
    Controls.Add(tooltip);
    tooltip.UpdateDisplay(e.Data);
    tooltip.Show();
}

But it shows up in the background (I can handle that) and, sadly, is confined to the window...


EDIT: Here is what I ended up doing...

I could not get the ToolTip control provided with .NET to work. This is mainly, because I'm trying to show tooltips for "hot spots" in a user drawn control (think a plot of function points, show additional items for the points). The ToolTip control would really like to only show when a user first enters a control - manually showing it does not seem to work. I tried. Long and hard.

So, this ToolTipWindow class can be used to show a control in a frameless window. I have added an Offset property, so it can be shown at an offset to the current mouse position.

/// <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);    
        }
    }
}

To show the tooltip, you can catch the MouseHover and MouseMove events. Check first, if you are above a "hot spot" and show the tooltip. In MouseMove, hide the tooltips if you are not above a "hot spot". Also, on closing the window, make sure you also close all tooltip windows!

Note: The MouseHover event will only show up the first time the mouse enters a control. If you want it to show up repeatedly (as in the case of detecting "hot spots"), you should add code like the following to the control containing the "hot spots":

    #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

解决方案

Your code has a serious problem, it adds a control to the user control every time the mouse hovers but never removes them.

First, make very sure that the built-in ToolTip component doesn't already solve your problem. It should, it behaves the way your describe. Note that it has the OwnerDraw property, it allows you to customize its appearance.

Creating your own is tricky. A tool tip is a fairly unusual window, it isn't a child control like all other WF controls. It is a top-level window, which allows it to overlap other windows and extend past the client area of the container window. The only class in Windows Forms that behaves this way is the Form class. Using a borderless form to implement your custom tool tip is possible.

The trickiest part is ensuring that it moves when the parent form of your user control moves. You'll have to iterate the Parent property of the UC until you find a Form, then subscribe the LocationChanged, VisibleChanged and FormClosing events. You'll also should wire the UC's ParentChanged and HandleDestroyed events.

这篇关于如何使在Windows.Forms的浮动(提示)控制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆