Check this out: I overloaded your Render function to accept a Graphics
object to redraw only the highlighted Bar. This is much more efficient
than invalidating and redrawing all the bars. I also improved your mouse
move event.
Public Class bartest
Inherits System.Windows.Forms.UserControl
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'UserControl overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
'
'bartest
'
Me.Name = "bartest"
End Sub
#End Region
Private barItemList As New ArrayList
Public i_barHeight As Integer = 10
Public i_barSpaceing As Integer = 3
Private Sub bartest_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.UpdateStyles()
End Sub
Public Sub start()
Dim a As Integer
For a = 1 To 10
Dim bi As New BarItem()
bi.Owner = Me
bi.orderNumb = a
bi.SetStart = a * 3.1 * a
bi.SetEnd = bi.SetStart * 2
barItemList.Add(bi)
Next
End Sub
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
ControlPaint.DrawBorder3D(e.Graphics, 0, 0, Me.Width,
Me.Height, Border3DStyle.Sunken, Border3DSide.All)
Dim bi As BarItem
For Each bi In barItemList
bi.Render(e)
Next
End Sub
Dim current As BarItem
Private Sub bartest_MouseMove(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
Dim bi As BarItem
If Not current Is Nothing Then
If current.rectangle.Contains(e.X, e.Y) Then
Exit Sub
Else
Dim grfx As Graphics = Me.CreateGraphics
current.MouseOver = False
current.Render(grfx)
grfx.Dispose()
current = Nothing
End If
End If
For Each bi In barItemList
If bi.rectangle.Contains(e.X, e.Y) Then
bi.MouseOver = True
current = bi
Dim grfx As Graphics = Me.CreateGraphics
current.Render(grfx)
grfx.Dispose()
Exit For
End If
Next
End Sub
' Private Sub bartest_MouseHover(ByVal sender As Object, ByVal e
As System.EventArgs) Handles MyBase.MouseHover
' Dim bi As BarItem
' For Each bi In barItemList
' If bi.rectangle.Contains(e.X, e.Y) Then
' bi.MouseOver = True
' Invalidate()
' Exit For
' Else
' bi.MouseOver = False
' Invalidate()
' End If
' Next
' End Sub
Private Sub bartest_MouseDown(ByVal sender As Object, ByVal e As
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
Dim bi As BarItem
For Each bi In barItemList
If bi.rectangle.Contains(e.X, e.Y) Then
bi.MouseOver = True
bi.MouseClick = True
Invalidate()
Exit For
Else
bi.MouseOver = False
bi.MouseClick = False
Invalidate()
End If
Next
End Sub
End Class
Public Class BarItem
Implements IMouseCommands
Private i_startNum As Integer
Private i_endNum As Integer
Private bt_owner As bartest
Private r_rectangle As rectangle
Private i_orderNum As Integer = 1
Private b_mouseover As Boolean = False
Private b_mouseclick As Boolean = False
Public Property orderNumb() As Integer
Get
Return i_orderNum
End Get
Set(ByVal Value As Integer)
i_orderNum = Value
End Set
End Property
Public Property SetStart() As Integer
Get
Return i_startNum
End Get
Set(ByVal Value As Integer)
i_startNum = Value
End Set
End Property
Public Property SetEnd() As Integer
Get
Return i_endNum
End Get
Set(ByVal Value As Integer)
i_endNum = Value
End Set
End Property
Public Property rectangle() As rectangle
Get
Return r_rectangle
End Get
Set(ByVal value As rectangle)
r_rectangle = value
End Set
End Property
Public Property Owner() As bartest
Get
Return bt_owner
End Get
Set(ByVal Value As bartest)
bt_owner = Value
End Set
End Property
Public Sub Render(ByVal e As PaintEventArgs)
Dim startColor As Drawing.Color
Dim endColor As Drawing.Color
If b_mouseover = False Then
startColor = Color.LightBlue
endColor = Color.Blue
Else
startColor = Color.Yellow
endColor = Color.YellowGreen
End If
Dim rect As New Rectangle(i_startNum, (i_orderNum *
bt_owner.i_barHeight) + (i_orderNum * bt_owner.i_barSpaceing), i_endNum,
bt_owner.i_barHeight)
Dim rectshad As New Rectangle(i_startNum + 2, (i_orderNum *
bt_owner.i_barHeight) + (i_orderNum * bt_owner.i_barSpaceing) + 2,
i_endNum, bt_owner.i_barHeight)
r_rectangle = rect
Dim br As New Drawing2D.LinearGradientBrush(rect, startColor,
endColor, Drawing2D.LinearGradientMode.Vertical)
e.Graphics.FillRectangle(New SolidBrush(Color.FromArgb(100, 0,
0, 0)), rectshad)
e.Graphics.FillRectangle(br, rect)
If b_mouseover = True Then
e.Graphics.DrawRectangle(New Pen(Color.White), rect)
End If
br.Dispose()
' do boarder
End Sub
Public Sub Render(ByVal e As Graphics)
Dim startColor As Drawing.Color
Dim endColor As Drawing.Color
If b_mouseover = False Then
startColor = Color.LightBlue
endColor = Color.Blue
Else
startColor = Color.Yellow
endColor = Color.YellowGreen
End If
Dim rect As New Rectangle(i_startNum, (i_orderNum *
bt_owner.i_barHeight) + (i_orderNum * bt_owner.i_barSpaceing), i_endNum,
bt_owner.i_barHeight)
Dim rectshad As New Rectangle(i_startNum + 2, (i_orderNum *
bt_owner.i_barHeight) + (i_orderNum * bt_owner.i_barSpaceing) + 2,
i_endNum, bt_owner.i_barHeight)
r_rectangle = rect
Dim br As New Drawing2D.LinearGradientBrush(rect, startColor,
endColor, Drawing2D.LinearGradientMode.Vertical)
e.FillRectangle(New SolidBrush(Color.FromArgb(100, 0, 0, 0)),
rectshad)
e.FillRectangle(br, rect)
If b_mouseover = True Then
e.DrawRectangle(New Pen(Color.White), rect)
End If
br.Dispose()
' do boarder
End Sub
Public Property MouseClick() As Boolean Implements
IMouseCommands.MouseClick
Get
Return b_mouseclick
End Get
Set(ByVal Value As Boolean)
b_mouseclick = Value
If Value = True Then
MessageBox.Show(Me.orderNumb)
End If
End Set
End Property
Public Property MouseOver() As Boolean Implements
IMouseCommands.MouseOver
Get
Return b_mouseover
End Get
Set(ByVal Value As Boolean)
b_mouseover = Value
End Set
End Property
End Class
' mouse commands interface
' this is not complete! just for an example
Public Interface IMouseCommands
Property MouseOver() As Boolean
Property MouseClick() As Boolean
End Interface