Home > Mobile >  C# - Animate a Winforms Control
C# - Animate a Winforms Control

Time:08-07

I'll try to get straight to the point, I'm trying to develop some sort of "animation" for a control in winforms that will run in a new thread than the main one.

So the code I used for the animation is the one I leave you below (a label control that scrolls up pixel by pixel every few seconds until it reaches 0 pixels):

private void LabelAnimation(int amount)
{
    this.Invoke((MethodInvoker)delegate
    {
        int currentX = Label.Location.X;

        Label.Text = amount.ToString();

        for (int h = 1; h < 7; h  )
        {
            int subtractHeight = h;
            int currentY = Label.Location.Y;

            Label.Location = new Point(currentX, (currentY - subtractHeight));

            Thread.Sleep(200);
        }
    });
}

And the method in which the new thread is created:

private void ExecuteAnimation()
{
    Thread t = new Thread(() => LabelAnimation(100));
    t.Start();
}

The problem is that in itself it works but on a graphic level it sucks, I mean, instead of moving the entire control, the text string remained in the same position while the rectangle of the label moved in the indicated direction, covering its own string.

CodePudding user response:

System.Windows.Forms.Timer runs on a separate thread.
It`s recommended to use a timer instead of sleeping the thread.
Here is one way to achieve this:

private System.Windows.Forms.Timer timer;
private int amount = 100;
private void ExecuteAnimation()
{
    // Set DoubleBuffered to true for smoother animation 
    this.DoubleBuffered = true;
    if (timer == null)
    {
        timer = new System.Windows.Forms.Timer();
        timer.Interval = 100;
        timer.Tick  = timer_tick;
    }

    timer.Start();
}

private void timer_tick(object? sender, EventArgs e)
{
    this.Invoke(new Action(() =>
    {
        int currentX = label1.Location.X;
        label1.Text = amount.ToString();

        if (label1.Location.Y > 0)
        {
            label1.Location = new Point(currentX, label1.Location.Y - 1);
        }
       

    }));
}

OUTPUT:

enter image description here

  • Related