Member Avatar for Unhnd_Exception
Unhnd_Exception

Heres a way to eliminate flickering or create a fade effect on a panel or anything else.

If anyone has a technique that would be more effective, please post it.


When double buffering doesn't fix a flicker problem on a panel you can use a picture box to mask it and create a fade effect.

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) Handles Button1.Click

        'Create a Picture box to do the fading
        'Set it to invisible and place it over the panel to mask.
        Dim picBox As New PictureBox
        picBox.Location = FlowLayoutPanel1.Location
        picBox.Size = FlowLayoutPanel1.Size
        picBox.Image = New Bitmap(FlowLayoutPanel1.Size.Width, _
                                  FlowLayoutPanel1.Size.Height, _
                                  Imaging.PixelFormat.Format32bppArgb)
        picBox.BackgroundImage = New Bitmap(FlowLayoutPanel1.Size.Width, _
                                            FlowLayoutPanel1.Size.Height, _
                                            Imaging.PixelFormat.Format32bppArgb)
        picBox.Visible = False
        Me.Controls.Add(picBox)
        picBox.BringToFront()

        'Draw the current items in the panel to the picBox's image
        FlowLayoutPanel1.DrawToBitmap(picBox.Image, picBox.ClientRectangle)

        'Now show the picbox.  There will now be a mask over the  
        'flowlayout panel of what it looks like now
        '*comment out this next line and the call to fade below to see flickering
        picBox.Visible = True

        'Clear out all the controls and add new controls
        FlowLayoutPanel1.Controls.Clear()
        Randomize()
        For i = 0 To Rnd() * 100 + 1
            Dim b As New Button
            b.BackColor = Color.FromArgb(255, 255, 255, Rnd() * 255)
            FlowLayoutPanel1.Controls.Add(b)
        Next

        'Draw the new items in the panel to the picBox's background image.
        FlowLayoutPanel1.DrawToBitmap(picBox.BackgroundImage, _
                                      picBox.ClientRectangle)


        'The picBox now has an image of the old panel on top and the new 
        'panel on the bottom. Fade out the old image panel.  
        '*If you don't want fading but want to eliminate flickering then
        'comment out the fade sub.
        Fade(picBox, 0.25)

        'Get rid of the picBox and its images
        picBox.BackgroundImage.Dispose()
        picBox.Image.Dispose()
        picBox.Dispose()
    End Sub

    Private Sub FlowLayoutPanel1_ControlRemoved(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles FlowLayoutPanel1.ControlRemoved
        e.Control.Dispose()
    End Sub

    Private Sub Fade(ByRef picBox As PictureBox, ByVal Interval As Double)
        'Interval in seconds
        If Interval <= 0 Then Exit Sub

        Dim [then] As Double = DateAndTime.Timer
        Dim PercentRemaining As Double = 0

        'Keep fading the image while there's still time
        Do While PercentRemaining < 1

            FadeBitmap(picBox.Image, 255 - (255 * PercentRemaining))

            'redraw the picBox so it shows the new faded image
            picBox.Invalidate()
            picBox.Update()

            'Calculate the % of time remaining
            PercentRemaining = (DateAndTime.Timer - [then]) / Interval
        Loop

    End Sub

    Private Sub FadeBitmap(ByRef BitmapToFade As Bitmap, ByRef Alpha As Double)
        If Alpha > 255 Then Alpha = 255
        If Alpha < 0 Then Alpha = 0

        Dim bmpData As System.Drawing.Imaging.BitmapData = _
            BitmapToFade.LockBits(New Rectangle(Point.Empty, BitmapToFade.Size), _
                                  Drawing.Imaging.ImageLockMode.ReadWrite, _
                                  BitmapToFade.PixelFormat)
        Dim ptr As IntPtr = bmpData.Scan0
        Dim Bytes(bmpData.Stride * BitmapToFade.Height - 1) As Byte

        System.Runtime.InteropServices.Marshal.Copy(ptr, Bytes, 0, Bytes.Length)

        For i = 3 To UBound(Bytes) Step 4
            Bytes(i) = Alpha
        Next

        System.Runtime.InteropServices.Marshal.Copy(Bytes, 0, ptr, Bytes.Length)

        BitmapToFade.UnlockBits(bmpData)
        bmpData = Nothing
        Bytes = Nothing
        ptr = IntPtr.Zero
    End Sub

End Class
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.