grandangelo
grandangelo

Reputation: 202

WindowsForm - Flicker after resize

I've a WinForm application (double buffer enabled) with a TableLayoutPanel containing some DataGridView, some ActiveX control (from NI TestStand) and some labels. I added some code to Form CellPaint event to draw borders where I need.

One label is showing, via Systems.Windows.Forms.Timer, the actual DateTime, incrementing each second. At each update the form is flickering. If I comment the code in CellPaint event, flickering stops.

Adding:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

solves the flickering issue with CellPaint code enabled, but only if I don't resize the form. After resize, flickering starts and never stops.

I tried several proposal found here on SO, with no luck, suspending layout as suggester here, using reflection to enable double buffering on each control.

How can I avoid the flickering also after the resize?

EDIT: Here below the code related to Cellpaint event:

private void LayoutMainWindow_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    SuspendLayout();
    if (e.Row == 0 && e.Column > 0)
    {
        DrawBottomBorder(e, 1);
    }
    if (e.Row == 1 && e.Column != 0)
    {
        DrawBottomBorder(e, 2);
    }
    if (e.Row <= 8 && e.Column == 0)
    {
        DrawRightBorder(e, 2);
    }
    if (e.Row == 2 && e.Column == 0)
    {
        DrawBottomBorder(e, 2);
    }
    if ((e.Row >= 2 && e.Row <= 7) && e.Column == 2)
    {
        DrawRightBorder(e, 2);
    }
    if (e.Row == 7 && e.Column <= 4)
    {
        DrawBottomBorder(e, 2);
    }
    if (e.Row >= 8 && e.Row <= 9)
    {
        DrawBottomBorder(e, 2);
    }
    if (e.Row == 9 && e.Column == 0)
    {
        DrawRightBorder(e, 2);
    }
    ResumeLayout();
}

private static void DrawRightBorder(TableLayoutCellPaintEventArgs e, float width)
{
    Rectangle r = e.CellBounds;
    using (Pen pen = new Pen(Color.Gray, width))
    {
        e.Graphics.DrawLine(pen, r.X + r.Width, r.Y, r.X + r.Width, r.Y + r.Height);
    }
}

private static void DrawBottomBorder(TableLayoutCellPaintEventArgs e, float width)
{
    Rectangle r = e.CellBounds;
    using (Pen pen = new Pen(Color.Gray, width))
    {
        e.Graphics.DrawLine(pen, r.X, r.Y + r.Height, r.X + r.Width, r.Y + r.Height);
    }
}

Upvotes: 0

Views: 1023

Answers (1)

grandangelo
grandangelo

Reputation: 202

Thanks to TaW suggestion, as far as CellPaint is related to a TableLayout containing all the controls inside the Form:

private static void SetDoubleBuffered(Control c)
{
    if (System.Windows.Forms.SystemInformation.TerminalServerSession)
        return;
    System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
    System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance);
    aProp.SetValue(c, true, null);
}

And then:

SetDoubleBuffered(LayoutMainWindow);

It fixes my issue. Thank you very much guys.

Upvotes: 2

Related Questions