2010-03-17 2 views
3

장면 : UserControl을 호스팅하는 폼 (작음) 양식.Windows.Forms에서 부동 (툴팁) 컨트롤을 만드는 방법?

플롯 : UserControl이 호버 이벤트를 발생시킬 때마다 툴팁 방식으로 그래픽 정보를 표시합니다. 사용자가 마우스를 움직이면 다시 사라지게됩니다.

Notes : 각 도구 설명은 정보를 그래픽 방식으로 표시하는 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과 함께 제공되지 않을 수 있습니다. 이것은 주로 사용자가 그린 컨트롤에서 "핫스팟"에 대한 툴팁을 표시하려고하기 때문에 (기능 점수의 플롯을 생각하고 포인트에 대한 추가 항목 표시). 도구 설명 컨트롤은 실제로 사용자가 처음 컨트롤을 입력 할 때만 표시하고 싶습니다. 수동으로 표시하면 작동하지 않는 것 같습니다. 나는 노력했다. 길고 어렵다.

따라서이 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);  
     } 
    } 
} 

당신이 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 
+0

국경없는 TopMost 양식 도움말이 표시됩니까? – fre0n

+0

예, fre0n, 그럴 것입니다. 지금 당장이 경로를 탐색 중입니다. 완료되면이 작업을 수행하는 클래스의 소스를 게시합니다.) –

답변

5

귀하의 코드가 심각한을 가지고 : 당신이 그것을 반복 ("핫스팟"을 감지의 경우)를 표시하려면, 당신은 "핫 스팟"를 포함하는 컨트롤에 다음과 같은 코드를 추가해야합니다 문제가 발생하면 마우스를 움직일 때마다 사용자 정의 컨트롤에 컨트롤을 추가하지만 절대 제거하지는 않습니다.

먼저 기본 제공 도구 설명 구성 요소가 아직 문제를 해결하지 않았는지 확인하십시오. 그것은 당신이 묘사하는 방식대로 행동해야합니다. OwnerDraw 속성을 가지고 있으므로 모양을 사용자 지정할 수 있습니다.

나만의 작품 만들기는 까다 롭습니다. 도구 설명은 매우 특이한 창이며 다른 모든 WF 컨트롤과 마찬가지로 하위 컨트롤이 아닙니다. 최상위 창으로 다른 창을 겹치게하고 컨테이너 창의 클라이언트 영역을지나 확장 할 수 있습니다. 이 방식으로 동작하는 Windows Forms의 유일한 클래스는 Form 클래스입니다. 경계선없는 양식을 사용하여 사용자 정의 도구 팁을 구현할 수 있습니다.

가장 까다로운 부분은 부모 컨트롤이 움직일 때 사용자가 움직이는 부분입니다. Form을 찾고 LocationChanged, VisibleChanged 및 FormClosing 이벤트를 구독 할 때까지 UC의 Parent 속성을 반복해야합니다. 또한 UC의 ParentChanged 및 HandleDestroyed 이벤트를 연결해야합니다.

+0

지금 도구 설명 구성 요소 경로를 사용할 것입니다. Popup 이벤트를 취소 한 후 다시 발생시키는 방법에 대한 아이디어가 있습니까? 이는 도구 팁에 표시되는 컨트롤에 핫 스폿이 있기 때문에 콜드 스팟에 대한 팁을 표시하지 않으므로 취소됩니다. –

+0

MouseHover 이벤트는 한 번만 발생합니다. 팁을 다시 표시하려면 MouseMove가 필요합니다. ToolTip에는 첫 번째 팁 시간이 초과되면 팁을 두 번 표시하지 못하도록하는 "기능"이 내장되어 있습니다. –

+0

"기능"을 종료 할 수 있습니까? –

관련 문제