VB.NET自定义绘制控制内存使用

时间:2014-10-10 09:45:54

标签: vb.net

我有很多自定义控件,当鼠标悬停在它们上面时会改变颜色。不幸的是,内存使用天空火箭反复悬停。它开始时约为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

0 个答案:

没有答案