Recently I realized that more and more I wanted to create buffered graphics instead of the traditional direct use of a graphics object.



I have recently come up with this class that makes things easier. I wanted to share it with the community, so please enjoy.

Example of the GraphicsFrame Class's Usage:
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim Frame As New GraphicsFrame(Me.Handle, Me.ClientRectangle.Size)
        With Frame.Graphics
            .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            .Clear(Me.BackColor)
            .FillEllipse(Brushes.Red, New Rectangle(10, 10, 100, 100))
            .DrawEllipse(Pens.Green, New Rectangle(10, 10, 100, 100))
            .DrawString("Hello world!", New Font("Consolas", 12), Brushes.Black, New Point(10, 10))
        End With
        Frame.Render()
        Frame.Dispose()
    End Sub
End Class

The GraphicsFrame Class:
Option Strict On
Option Explicit On
Option Infer Off
Public Class GraphicsFrame
    Implements IDisposable
    Private disposedValue As Boolean
    Private BackBuffer As System.Drawing.BufferedGraphics = Nothing
    Public ReadOnly Property Graphics() As System.Drawing.Graphics
        Get
            Return Me.BackBuffer.Graphics
        End Get
    End Property
    Public Sub New(ByVal canvas As System.Windows.Forms.Control)
        BufferedGraphicsManager.Current.MaximumBuffer = New Size(canvas.ClientRectangle.Width + 1, canvas.ClientRectangle.Height + 1)
        Me.BackBuffer = BufferedGraphicsManager.Current.Allocate(canvas.CreateGraphics, New Rectangle(0, 0, canvas.ClientRectangle.Width, canvas.ClientRectangle.Height))
    End Sub
    Public Sub New(ByVal canvasGraphics As Graphics, maximumBuffer As Size)
        BufferedGraphicsManager.Current.MaximumBuffer = New Size(maximumBuffer.Width + 1, maximumBuffer.Height + 1)
        Me.BackBuffer = BufferedGraphicsManager.Current.Allocate(canvasGraphics, New Rectangle(0, 0, maximumBuffer.Width, maximumBuffer.Height))
    End Sub
    Public Sub New(ByVal handle As IntPtr, maximumBuffer As Size)
        BufferedGraphicsManager.Current.MaximumBuffer = New Size(maximumBuffer.Width + 1, maximumBuffer.Height + 1)
        Me.BackBuffer = BufferedGraphicsManager.Current.Allocate(Graphics.FromHwnd(handle), New Rectangle(0, 0, maximumBuffer.Width, maximumBuffer.Height))
    End Sub
    Public Sub New(ByVal canvas As Image)
        BufferedGraphicsManager.Current.MaximumBuffer = New Size(canvas.Width + 1, canvas.Height + 1)
        Me.BackBuffer = BufferedGraphicsManager.Current.Allocate(Graphics.FromImage(canvas), New Rectangle(0, 0, canvas.Width, canvas.Height))
    End Sub
    Public Sub New(ByVal canvas As Bitmap)
        BufferedGraphicsManager.Current.MaximumBuffer = New Size(canvas.Size.Width + 1, canvas.Size.Height + 1)
        Me.BackBuffer = BufferedGraphicsManager.Current.Allocate(Graphics.FromImage(canvas), New Rectangle(0, 0, canvas.Width, canvas.Height))
    End Sub
    Public Sub Render()
        If Not BackBuffer Is Nothing Then BackBuffer.Render()
    End Sub
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                Me.BackBuffer = Nothing
                GC.Collect()
            End If
        End If
        Me.disposedValue = True
    End Sub
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
End Class