Click here to Skip to main content
15,891,657 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi I have the following code which resizes a table layout column.

I have written it so it animates out, kind of like a hidden menu.

C#
public void ToggleMenu()
        {
            if (this.DesignMode)
            {
            }
            else
            {
                if (displayMenu)
                {
                    for (float i = 25; i >= 0; i--)
                    {
                        this.ColumnStyles[0].SizeType = SizeType.Percent;
                        this.ColumnStyles[0].Width = i;

                        this.Refresh();
                    }
                    displayMenu = false;
                }
                else
                {
                    for (float i = 0; i <= 25; i++)
                    {
                        this.ColumnStyles[0].SizeType = SizeType.Percent;
                        this.ColumnStyles[0].Width = i;
                        this.Refresh();
                    }
                    displayMenu = true;
                }
            }
        }


What I would like to know is if anyone knows a more efficient way to do this? As this can be a bit jittery at times even with double buffering.

Another issue I have is with the controls in the other columns of the tablelayout panel, these also jitter when the panel is resizing.

Any suggestions?

Thanks in advance.
Posted
Comments
BillWoodruff 13-Feb-14 12:15pm    
I wish you all success, but I have to tell you that I've never seen a satisfying animation done with resizing of Controls in Windows Forms, and, given what I know of the TableLayoutPanel, it would be one of the worst Control to try and animate with.

If you want fluid animations, I recommend WPF, or that other stuff from outside Microsoft, HTML5, jQuery, JavaScript, SVG, yada, yada, yada.

1 solution

You should avoid calling Refresh in a loop. The UI is blocked for the duration of the animation.

1. create timer that fires at the desired animation frame rate.

2. timer delegate updates the percentage and trigger a re-paint of the window.

3. cancel the timer at the end of the animation.

4. use Invalidate, not Refresh.

5. Add the following to the parent form window constructor AND the constructor of your class that derives from tableLayoutPanel:

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);


I've tested this. It works. You will see a tiny amount of wiggle (but no flicker) in one or more vertical grid lines. This caused by rounding errors in the percentage driven resizing of the columns.

public partial class Form1 : Form
{
    private Timer timer = new Timer();
    float move = -1.0f;

    public Form1()
    {
        InitializeComponent();
        timer.Tick += new EventHandler(timer_Tick);
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        tableLayoutPanel1.ColumnStyles[0].Width += move;
        if (tableLayoutPanel1.ColumnStyles[0].Width <= 0.0) move = 1.0f;
        else if (tableLayoutPanel1.ColumnStyles[0].Width > 50.0) move = -1.0f;
        Invalidate(true);
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        timer.Stop();
    }
}


class Table : System.Windows.Forms.TableLayoutPanel
{
    public Table()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
    }
}



An alternative is to create a rubber band that animates the rectangular area that grows or shrinks. This is drawn on top of the existing controls so it does not require a repaint of the area.
 
Share this answer
 
v4
Comments
Member 10111284 14-Feb-14 4:12am    
Thank you for your response although this is not perfect I think this is the best solution for the time being, I will let you all know if I manage to optimize this.

Thanks

Kind Regards

Chris

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900