在自定义用户控件的绘制图标图像上显示工具提示 [英] Display tool tip on drawn icon image of custom user control

查看:77
本文介绍了在自定义用户控件的绘制图标图像上显示工具提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究我的第一个自定义用户控件。自定义控件继承UserControl。用户控件包含绘制的矩形,圆形和图标图像的组合。当用户将鼠标悬停在控件的图像部分上时,我想显示工具提示。图像是使用drawicon创建的。然后我在我的控件中有一个鼠标移动事件,可以检测鼠标何时在图标上。这个逻辑一切正常。我遇到的问题是,在工具提示消失后,它会擦除​​控件的一部分。我试图弄清楚重新绘制控件的正确方法,但我没有运气。



我尝试了什么:



以下是我绘制控件的方法:

受保护的覆盖Sub OnPaint(ByVal e As System.Windows。 Forms.PaintEventArgs)

Dim rect As System.Drawing.Rectangle = e.ClipRectangle
Dim g As Graphics = e.Graphics
g.SmoothingMode = SmoothingMode.HighQuality

'抽机床
DrawBed(g,rect)

'抽出并定位机头
DrawHead(g,rect,_HeadPosInInches)

结束子

私人子DrawBed(ByVal g As Graphics,ByVal CtlRect As System.Drawing.Rectangle)

'拉床

'根据控件大小调整床的大小
_BedWidth = CInt(CtlRect.Width * _BedWidthFactor)
_BedHeight = CInt(CtlRect.Height * _BedHeightFact或者)

'控制中心床位
_BedYBorder = CInt((CtlRect.Height - _BedHeight)/ 2)
_BedXBorder = CInt(CtlRect.Width - _BedWidth)

'为床创建一个新的矩形
Dim BedXLoc As Integer = 0

如果HeadTravelDir = 1那么
BedXLoc = _BedXBorder
Else
BedXLoc = 0
结束如果

Dim BedRect为新矩形(BedXLoc,_BedYBorder,_BedWidth,_BedHeight)

'填充床
使用Brush1作为新的SolidBrush(_BedColor)
g.FillRectangle(Brush1,BedRect)
结束使用

'创建床边框
使用Pen1作为新笔( Color.Black,1)
g.DrawRectangle(Pen1,BedRect)
结束使用

结束子





以下是我在屏幕上绘制图标图像的方法:



 Dim TargetX As Integer = 0 
Dim TargetY As Integer = 0
Dim TargetWidth As Integer = _BedYBorder
Dim TargetHeight As Integer = _BedYBorder

If _HeadTravelDir = 1 Then
TargetX = HeadRect.X + HeadRect.Width + 5
否则
TargetX = HeadRect.X - 5 - _BedYBorder
结束如果

Dim DashboardIcon作为新图标( U:\ photos \ DashboardIcons \ Question.ico)
Dim TargetRect为新的矩形(TargetX,TargetY,TargetWidth,TargetHeight)
IconRect = TargetRect
g.DrawIcon(DashboardIcon) ,TargetRect)





以下是我检测鼠标何时超过图标图像的方法:



 Private Sub ctlGantry_MouseMove(ByVal sender As Object,ByVal e As System.Windows.Forms.MouseEventArgs)Handles Me.MouseMove 

'检查是否鼠标如果超过图标
如果IconRect.Contains(e.Location)那么
Debug.WriteLine(e.Location.ToString& 超过了图标& Me.Name)
_IconMouseOver = True
'Me.ToolTip1.Show(test,Me)

Else
_IconMouseOver = False
'Me .ToolTip1.Hide(Me)
'Me.Invalidate()
End if
End Sub





我试过在mousemove和mousehover事件中显示工具提示,但我得到了类似的结果。如果我试图在鼠标悬停在图标上时无效,我会收到很多闪烁。当我将鼠标移动到图标上的不同位置时,背景控件也不会重新绘制。我不确定这是否与同一问题有关,但我也遇到了一个问题,在我将鼠标悬停在控件上几秒钟然后回来并重新启动后,图标将不再出现。如果我重新绘制控件并再次尝试,则工具提示将重新出现。我非常接近能够包装这个控件,但我需要首先解决这个问题。有什么想法吗?

解决方案

这是一个适合你的工作样本:

 公开  UserControl1 

公共 Sub New ()

InitializeComponent()
AddTootip()
Recalc()

结束 Sub

私有工具提示作为工具提示

私人 Sub AddTootip()

工具提示= 工具提示()使用
{
.AutoPopDelay = 5000
。 InitialDelay = 1000
.ReshowDelay = 500
.ShowAlways = True
}
Tooltip.SetToolTip( Me 测试工具提示1 2 3 ...

结束 Sub

私人框( 9 作为矩形

私有 Sub UserControl1_Paint(发件人作为 对象,e 正如 PaintEventArgs)句柄 MyBase .Paint

Dim gr = e.Graphics
Dim br = SolidBrush(Color.Red)

对于 index = 0 9
gr.FillRectangle(br,boxes(index))
下一步

结束 Sub

私有 Sub UserControl1_MouseMove(sender As Object ,e As MouseEventArgs)句柄 MyBase .MouseMove

对于 index = 0 9
如果框(索引).Contains(e.Location)然后
Tooltip.ToolTipTitle = < span class =code-string> Box + CStr (index + < span class =code-digit> 1 )
退出 Sub
结束 如果
下一步
Tooltip.ToolTipTitle = UserControl background ...

结束 Sub

私人 Sub UserControl1_Resize(发件人作为 对象,e As EventArgs)
Recalc()
结束 Sub

私人 Sub Recalc()

Dim hoffset =高度/ 11
Dim woffset = Width / 11
Dim sz = 大小(woffset,hoffset)

对于 index = 0 9
Dim pt = 点(索引* woffset,索引* hoffset)
boxes(index)= 矩形(pt,sz)
下一步

Invalidate()

结束 Sub

结束


I have been working on my first custom user control. The custom control inherits UserControl. The user control contains a combination of drawn rectangles, circles and a icon image. I would like to display a tool tip when the user hovers the mouse over the image portion of the control. The image was created by using drawicon. I then have a mouse move event in my control that detects when the mouse is over the icon. That logic all works properly. What I am having a problem with is that after the tool tip disappears, it erases the part of the control is was hovering over. I am trying to figure out the proper way to repaint the control but I am not having any luck.

What I have tried:

Here is how I am painting the control:

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        Dim rect As System.Drawing.Rectangle = e.ClipRectangle
        Dim g As Graphics = e.Graphics
        g.SmoothingMode = SmoothingMode.HighQuality

        'Draw the Machine Bed
        DrawBed(g, rect)

        'Draw and position the Machine Head
        DrawHead(g, rect, _HeadPosInInches)

    End Sub

    Private Sub DrawBed(ByVal g As Graphics, ByVal CtlRect As System.Drawing.Rectangle)

        'Draws the bed

        'Size the bed based on the control size
        _BedWidth = CInt(CtlRect.Width * _BedWidthFactor)
        _BedHeight = CInt(CtlRect.Height * _BedHeightFactor)

        'Center the bed within the control
        _BedYBorder = CInt((CtlRect.Height - _BedHeight) / 2)
        _BedXBorder = CInt(CtlRect.Width - _BedWidth)

        'Create a new rect for the bed
        Dim BedXLoc As Integer = 0

        If HeadTravelDir = 1 Then
            BedXLoc = _BedXBorder
        Else
            BedXLoc = 0
        End If

        Dim BedRect As New Rectangle(BedXLoc, _BedYBorder, _BedWidth, _BedHeight)

        'Fill the Bed
        Using Brush1 As New SolidBrush(_BedColor)
            g.FillRectangle(Brush1, BedRect)
        End Using

        'Create the Bed border
        Using Pen1 As New Pen(Color.Black, 1)
            g.DrawRectangle(Pen1, BedRect)
        End Using

    End Sub



Here is how I am drawing the icon image on the screen:

Dim TargetX As Integer = 0
Dim TargetY As Integer = 0
Dim TargetWidth As Integer = _BedYBorder
Dim TargetHeight As Integer = _BedYBorder

If _HeadTravelDir = 1 Then
   TargetX = HeadRect.X + HeadRect.Width + 5
Else
   TargetX = HeadRect.X - 5 - _BedYBorder
End If

Dim DashboardIcon As New Icon("U:\photos\DashboardIcons\Question.ico")
Dim TargetRect As New Rectangle(TargetX, TargetY, TargetWidth, TargetHeight)
IconRect = TargetRect
g.DrawIcon(DashboardIcon, TargetRect)



Here is how I am detecting when the mouse if over the icon image:

Private Sub ctlGantry_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove

        'Checks to see if the mouse if over the icon
        If IconRect.Contains(e.Location) Then
            Debug.WriteLine(e.Location.ToString & " is Over the Icon for " & Me.Name)
            _IconMouseOver = True
            'Me.ToolTip1.Show("test", Me)

        Else
            _IconMouseOver = False
            'Me.ToolTip1.Hide(Me)
            'Me.Invalidate()
        End If
    End Sub



I have tried displaying the tooltip in both the mousemove and the mousehover events but I get similar results. If I try to invalidate when the mouse is not over the icon, I get a lot of flickering. The background control also doesn't repaint when I move the mouse in a different position over the icon. I am not sure if this is related to the same issue but I also have a problem where the icon will no longer reappear after I hover on the control for a few seconds and then comeback and rehover. If I repaint the control and try it again, then the tooltip will reappear. I am very close to being able to wrap this control up but I need to figure this out first. Any ideas?

解决方案

Here is a working sample for you:

Public Class UserControl1

    Public Sub New()

        InitializeComponent()
        AddTootip()
        Recalc()

    End Sub

    Private Tooltip As ToolTip

    Private Sub AddTootip()

        Tooltip = New ToolTip() With
        {
            .AutoPopDelay = 5000,
            .InitialDelay = 1000,
            .ReshowDelay = 500,
            .ShowAlways = True
        }
        Tooltip.SetToolTip(Me, "Test tooltip 1 2 3...")

    End Sub

    Private boxes(9) As Rectangle

    Private Sub UserControl1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint

        Dim gr = e.Graphics
        Dim br = New SolidBrush(Color.Red)

        For index = 0 To 9
            gr.FillRectangle(br, boxes(index))
        Next

    End Sub

    Private Sub UserControl1_MouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.MouseMove

        For index = 0 To 9
            If boxes(index).Contains(e.Location) Then
                Tooltip.ToolTipTitle = "Box " + CStr(index + 1)
                Exit Sub
            End If
        Next
        Tooltip.ToolTipTitle = "UserControl background..."

    End Sub

    Private Sub UserControl1_Resize(sender As Object, e As EventArgs)
        Recalc()
    End Sub

    Private Sub Recalc()

        Dim hoffset = Height / 11
        Dim woffset = Width / 11
        Dim sz = New Size(woffset, hoffset)

        For index = 0 To 9
            Dim pt = New Point(index * woffset, index * hoffset)
            boxes(index) = New Rectangle(pt, sz)
        Next

        Invalidate()

    End Sub

End Class


这篇关于在自定义用户控件的绘制图标图像上显示工具提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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