我认为这是一个相当基本的问题,但我在这方面的花费时间要远远超过应该花的时间。
上下文如下:
我想创建一个自定义用户控件,它包含一个面板,其中垂直绘制3条线,控件应该以这样的方式工作:当值更改时,控件将使用更新的线位置重新绘制。
到目前为止,我的代码如下:
Public Class ColourValueBar
Private Position_Marker As Integer = 0
Private Position_Marker_LeftBound As Integer = 0
Private Position_Marker_RightBound As Integer = 0
Private render_Marker As Boolean = True
Private render_Left As Boolean = True
Private render_Right As Boolean = True
Private Shared myPenG As Pen = New Pen(Color.Green, 2)
Private Shared myPenM As Pen = New Pen(Color.Magenta, 4)
Public Property Marker() As Integer
Get
Return Position_Marker
End Get
Set(ByVal value As Integer)
Try
If (value < 0 Or value > 255) Then
Throw New Exception("ColourValueBar : Marker " & value & " is out of bounds")
End If
Position_Marker = value
Refresh()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Set
End Property
Public Property LeftBound() As Integer
Get
Return Position_Marker_LeftBound
End Get
Set(ByVal value As Integer)
Try
If (value < 0 Or value > 255) Then
Throw New Exception("ColourValueBar : LeftBound " & value & " is out of bounds")
End If
Position_Marker_LeftBound = value
Refresh()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Set
End Property
Public Property RightBound() As Integer
Get
Return Position_Marker_RightBound
End Get
Set(ByVal value As Integer)
Try
If (value < 0 Or value > 255) Then
Throw New Exception("ColourValueBar : RightBound " & value & " is out of bounds")
End If
Position_Marker_RightBound = value
Refresh()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Set
End Property
Public Sub New()
Try
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
Public Sub SetRendering(ByVal marker As Boolean, leftBound As Boolean, rightBound As Boolean)
Try
render_Marker = marker
render_Left = leftBound
render_Right = rightBound
Refresh()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
'Protected Overridable Sub ColourValueBar_Paint(sender As Object, e As PaintEventArgs)
Public Sub Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
Try
'Using g As Graphics = PNL_Gradient.CreateGraphics 'Me.CreateGraphics
If (render_Left) Then
e.Graphics.DrawLine(myPenM, New Point(Position_Marker_LeftBound, 0), New Point(Position_Marker_LeftBound, 56))
End If
If (render_Right) Then
e.Graphics.DrawLine(myPenM, New Point(Position_Marker_RightBound, 0), New Point(Position_Marker_RightBound, 56))
End If
If render_Marker Then
e.Graphics.DrawLine(myPenG, New Point(Position_Marker, 0), New Point(Position_Marker, 56))
End If
' PNL_Gradient.Refresh()
' End Using
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
我的主要形式的测试代码:
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
Dim Userbox As ColourValueBar = New ColourValueBar()
Userbox.Location = New Point(150, 145)
Userbox.Size = New Size(520, 63)
Userbox.Visible = True
Me.Controls.Add(Userbox)
Userbox.Marker = 155
Userbox.LeftBound = 100
Userbox.RightBound = 200
'Userbox.Draw()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
问题如下:
我可以从我的主窗体中绘制自定义控件,我可以看到面板。 更改值似乎没有做任何事情,我尝试绘制线条的尝试似乎都没有效果。
强制调用Draw()子函数不会显示任何行,但代码也不会抛出任何错误或异常。
我试过了:
我也无法从工具箱中拖放我的控件;并显示错误消息&#34;无法加载工具箱项目&#39; ColourValueBar&#39;。它将从工具箱中删除&#39;但以编程方式将其添加到表单似乎有效(据我所知,因为线条图似乎不起作用)
我错过了什么,或者我在做什么本来就错了?
提前致谢,
编辑:
编辑的例程覆盖了OnPaint,在第一次被激活时绘制得很好,但是在线消失的情况下没有正确更新:
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Try
Using g As Graphics = PNL_Gradient.CreateGraphics
&#39; MyBase.OnPaint(e)中
If (render_Left) Then
g.DrawLine(myPenM, New Point(Position_Marker_LeftBound, 0), New Point(Position_Marker_LeftBound, 56))
End If
If (render_Right) Then
g.DrawLine(myPenM, New Point(Position_Marker_RightBound, 0), New Point(Position_Marker_RightBound, 56))
End If
If render_Marker Then
g.DrawLine(myPenG, New Point(Position_Marker, 0), New Point(Position_Marker, 56))
End If
MyBase.OnPaint(e)
End Using
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
使用e参数作为抽屉的相同例程,它在外部边界容器上绘制线条,并正确更新,但面板上绘有线条:
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Try
' MyBase.OnPaint(e)
If (render_Left) Then
e.Graphics.DrawLine(myPenM, New Point(Position_Marker_LeftBound, 0), New Point(Position_Marker_LeftBound, 56))
End If
If (render_Right) Then
e.Graphics.DrawLine(myPenM, New Point(Position_Marker_RightBound, 0), New Point(Position_Marker_RightBound, 56))
End If
If render_Marker Then
e.Graphics.DrawLine(myPenG, New Point(Position_Marker, 0), New Point(Position_Marker, 56))
End If
MyBase.OnPaint(e)
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
最后的尝试与#2的工作方式相同:
Protected Sub MyPaint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Try
If (render_Left) Then
e.Graphics.DrawLine(myPenM, New Point(Position_Marker_LeftBound, 0), New Point(Position_Marker_LeftBound, 56))
End If
If (render_Right) Then
e.Graphics.DrawLine(myPenM, New Point(Position_Marker_RightBound, 0), New Point(Position_Marker_RightBound, 56))
End If
If render_Marker Then
e.Graphics.DrawLine(myPenG, New Point(Position_Marker, 0), New Point(Position_Marker, 56))
End If
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub