0

So I have a FlowLayoutPanel that gets populated with multiple user controls. These user controls have a gradient painted background color. On MouseEnter the color of the gradient changes (like a mouse over effect) and returns to normal on MouseLeave. This works great, however the FlowLayoutPanel flickers badly (even with it being double buffered) when scrolling. If I add the following code to my form, the scroll flicker goes away completely, and the MouseEnter/MouseLeave events of my user controls still fire, but the new background gradient is not painted to resemble the mouse over effect

Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Dim cp As CreateParams = MyBase.CreateParams
        cp.ExStyle = cp.ExStyle Or &H2000000 ' WS_CLIPCHILDREN

        Return cp
    End Get
End Property

The code to do the painting is in a public subroutine and is called like so

Call PaintMe(Me, ColorTranslator.FromOle(RGB(18, 18, 18)), _
                    ColorTranslator.FromOle(RGB(29, 29, 29)), _
                    ColorTranslator.FromOle(RGB(18, 18, 18)), _
                    Color.Black, True, True, 2)

Public Sub PaintMe(ByVal ctrl As Control, ByVal color1 As Color, color2 As Color, color3 As Color, ByVal border_color As Color, Optional ByVal correct_gama As Boolean = False, Optional ByVal has_border As Boolean = False, Optional ByVal border_width As Single = 0)
    ' Make the basic brush.
    Dim gBrush As LinearGradientBrush
    gBrush = New LinearGradientBrush(New Point(0, 0), New Point(0, ctrl.ClientSize.Height), _
                                     ColorTranslator.FromOle(RGB(color1.R, color1.G, color1.B)), _
                                     ColorTranslator.FromOle(RGB(color3.R, color3.G, color3.B)))

    gBrush.WrapMode = WrapMode.TileFlipX

    ' Define the colors.
    Dim color_blend As New ColorBlend
    color_blend.Colors = New Color() {ColorTranslator.FromOle(RGB(color1.R, color1.G, color1.B)), _
                                      ColorTranslator.FromOle(RGB(color2.R, color2.G, color2.B)), _
                                      ColorTranslator.FromOle(RGB(color3.R, color3.G, color3.B))}

    color_blend.Positions = New Single() {0.0, 0.5, 1.0}
    gBrush.InterpolationColors = color_blend
    gBrush.GammaCorrection = correct_gama

    ctrl.CreateGraphics().SmoothingMode = SmoothingMode.AntiAlias
    ctrl.CreateGraphics().FillRectangle(gBrush, ctrl.ClientRectangle)

    If has_border = True Then
        ' Create pen. 
        Dim myPen As New Pen(border_color, border_width)
        ' Create rectangle. 
        Dim rect As New Rectangle(0, 0, ctrl.ClientSize.Width, ctrl.ClientSize.Height)
        ctrl.CreateGraphics().DrawRectangle(myPen, rect)
    End If
End Sub

My question is, is there any other way to remove the flicker from the FlowLayoutPanel, or a way to still have the child controls on the form do the painting on the mouse events? Right now, the only PaintMe that fires are when the form actually loads the controls for the first time.

wruckie
  • 1,717
  • 1
  • 23
  • 34
Jay
  • 885
  • 1
  • 7
  • 9

0 Answers0