我有很多自定义控件,当鼠标悬停在它们上面时会改变颜色。不幸的是,内存使用天空火箭反复悬停。它开始时约为14mb,并在快速盘旋几次后射到100mb。
下面显示了一些代码,这是控件的生成,绘制和无效。我相信记忆问题将存在于某处。使用的内存似乎只在应用程序最小化时释放。
Public Sub New()
' This call is required by the designer.
InitializeComponent()
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw Or ControlStyles.UserPaint, True)
SetStyle(ControlStyles.Opaque, True)
' Add any initialization after the InitializeComponent() call.
Me.Invalidate()
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
Dim BorderColour As Color = ColourSchemes.GetLighterColourFromTheme
Dim FillColour As Color = ColourSchemes.GetNormalColourFromTheme
Dim CheckFillColour As Color = ColourSchemes.GetNormalColourFromTheme(ColourSchemes.HiddenTheme.SilverInterface)
Dim OutlineCheckColour As Color = ColourSchemes.GetNormalColourFromTheme
Dim InnerRect As New Rectangle(New Point(0, 0), New Size(Me.Width - 1, Me.Height - 1))
If CTRLRule = CTRLStyle.Classic Or CTRLRule = CTRLStyle.ClassicWithColour Then
'CLASSIC STYLE
Dim XY As Integer = 0
If CTRLBoxSize = 0 Then
XY = CalculateCheckSquare()
Else
XY = CTRLBoxSize
End If
Dim CheckRect As New Rectangle(New Point(5, ((Me.Height - XY + 2)) / 2), New Size(XY - 4, XY - 4))
Dim TextHeight As Integer = TextRenderer.MeasureText(Text, Font).Height
Dim TextArea As New Rectangle(New Point(5 + XY + 5, (Me.Height - TextHeight) / 2), New Size(Me.Width - (7 + XY), TextHeight))
If CTRLRule = CTRLStyle.Classic Then
Select Case Switcher
Case StyleSwitcher.Normal
OutlineCheckColour = ColourSchemes.GetNormalColourFromTheme(ColourSchemes.HiddenTheme.SilverInterface)
CheckFillColour = ColourSchemes.GetNormalColourFromTheme(ColourSchemes.HiddenTheme.SilverInterface)
Case StyleSwitcher.Rollover
OutlineCheckColour = ColourSchemes.GetLighterColourFromStyle(ColourStyle)
CheckFillColour = ColourSchemes.GetLighterColourFromStyle(ColourStyle)
If Checked = True Then
OutlineCheckColour = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
CheckFillColour = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
End If
Case StyleSwitcher.Depressed
OutlineCheckColour = ColourSchemes.GetDarkerColourFromStyle(ColourStyle)
CheckFillColour = ColourSchemes.GetDarkerColourFromStyle(ColourStyle)
End Select
Else
Select Case Switcher
Case StyleSwitcher.Normal
OutlineCheckColour = ColourSchemes.GetNormalColourFromTheme(ColourSchemes.HiddenTheme.SilverInterface)
Case StyleSwitcher.Rollover
OutlineCheckColour = ColourSchemes.GetLighterColourFromStyle(ColourStyle)
Case StyleSwitcher.Depressed
OutlineCheckColour = ColourSchemes.GetDarkerColourFromStyle(ColourStyle)
End Select
If Checked = True Then
BorderColour = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
CheckFillColour = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
OutlineCheckColour = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
End If
CheckFillColour = OutlineCheckColour
End If
e.Graphics.FillRectangle(New SolidBrush(FillColour), InnerRect)
e.Graphics.DrawRectangle(New Pen(BorderColour), InnerRect)
e.Graphics.DrawEllipse(New Pen(OutlineCheckColour, 2), CheckRect)
e.Graphics.DrawString(Text, Font, New SolidBrush(ColourSchemes.GetFontColourFromTheme), TextArea, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Near})
If Checked = True Then
Dim TSize As Integer = (CheckRect.Width / 6) 'WANT INNERDS TO FILL 3/4
e.Graphics.FillEllipse(New SolidBrush(CheckFillColour), New Rectangle(New Point(CheckRect.X + TSize, CheckRect.Y + TSize), New Size(CheckRect.Width - (TSize * 2), CheckRect.Height - (TSize * 2))))
End If
Else
'LIGHT STYLE
Dim LightPen As Color = ColourSchemes.GetLighterColourFromTheme
Dim LightPen2 As Color
Dim TextColour As Color = ColourSchemes.GetFontColourFromTheme
If CTRLRule = CTRLStyle.Light Then
LightPen2 = ColourSchemes.GetLighterColourFromTheme
Else
LightPen2 = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
If Me.Checked = True Then
TextColour = ColourSchemes.GetNormalColourFromStyle(ColourStyle)
End If
End If
e.Graphics.DrawLine(New Pen(ColourSchemes.GetDarkerColourFromTheme, 3), New Point(0, Me.Height - 1), New Point(Me.Width, Me.Height - 1))
Dim ArrowH As Integer = Me.Height - ((Me.Height - 8) / 2)
If Me.Checked = True Then
e.Graphics.DrawLine(New Pen(LightPen2, 2), New Point(Me.Width - 30, Convert.ToSingle(ArrowH)), New Point(Me.Width - 20, Convert.ToSingle(ArrowH - 8)))
e.Graphics.DrawLine(New Pen(LightPen2, 2), New Point(Me.Width - 10, Convert.ToSingle(ArrowH)), New Point(Me.Width - 20, Convert.ToSingle(ArrowH - 8)))
Else
e.Graphics.DrawLine(New Pen(LightPen, 2), New Point(Me.Width - 20, Convert.ToSingle(ArrowH)), New Point(Me.Width - 30, Convert.ToSingle(ArrowH - 8)))
e.Graphics.DrawLine(New Pen(LightPen, 2), New Point(Me.Width - 20, Convert.ToSingle(ArrowH)), New Point(Me.Width - 10, Convert.ToSingle(ArrowH - 8)))
End If
e.Graphics.DrawString(Text, Font, New SolidBrush(TextColour), InnerRect, New StringFormat With {.Alignment = StringAlignment.Near, .LineAlignment = StringAlignment.Center})
End If
End Sub
Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
MyBase.OnMouseLeave(e)
Switcher = StyleSwitcher.Normal
Me.Invalidate()
End Sub
Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
MyBase.OnMouseEnter(e)
Switcher = StyleSwitcher.Rollover
Me.Invalidate()
End Sub
编辑:在@Hans Passant评论之后,我更改了代码以使用"使用"声明。但是,这似乎在运行时没有任何影响。更改后的代码如下所示(假设我正确解释了注释)
e.Graphics.FillRectangle(New SolidBrush(FillColour), InnerRect)
e.Graphics.DrawRectangle(New Pen(BorderColour), InnerRect)
e.Graphics.DrawEllipse(New Pen(OutlineCheckColour, 2), CheckRect)
Using Brush As New SolidBrush(FillColour)
e.Graphics.FillRectangle(Brush, InnerRect)
End Using
Using Pen As New Pen(BorderColour, 1)
e.Graphics.DrawRectangle(Pen, InnerRect)
Pen.Color = OutlineCheckColour
Pen.Width = 2
e.Graphics.DrawEllipse(Pen, CheckRect)
End Using