How to make drawn points in winforms Paint event to be animated?

Chocolade 516 Reputation points
2022-09-21T01:01:16.377+00:00

The goal is to create loading label effect.

I created a new user control added a new List<PointF> type and updating and adding items to the List in a timer tick event.
then in the paint event i loop pver the List and draw the points.

now it's drawing nice 3 points. the problem is how to create the animation effect of the loading, meaning each time another point is deleted or something that make it looks like loading.

using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Drawing.Drawing2D;  
using System.Linq;  
using System.Text;  
using System.Threading;  
using System.Threading.Tasks;  
using System.Windows.Forms;  
  
namespace Test  
{  
    public partial class LoadingLabel : UserControl  
    {  
        private List<PointF> points = new List<PointF>();  
  
        public LoadingLabel()  
        {  
            InitializeComponent();  
  
            points.Add(new PointF(0, 0));  
  
            timer1.Enabled = true;  
        }  
  
        private void LoadingLabel_Load(object sender, EventArgs e)  
        {  
  
        }  
  
        private void LoadingLabel_Paint(object sender, PaintEventArgs e)  
        {  
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;  
              
            for (int i = 0; i < points.Count; i++)  
            {  
                e.Graphics.FillEllipse(Brushes.Red, points[i].X, points[i].Y, 20, 20);  
            }  
        }  
  
        int count = 0;  
        private void timer1_Tick(object sender, EventArgs e)  
        {  
            count++;  
  
            if (count < 3)  
            {  
                points.Add(new PointF(count * 20, 0));  
                //points = new List<PointF>();  
            }  
  
            //this.Invalidate();  
        }  
    }  
}  

If i will make the instance in the tick event it will not draw anything. if i will use the Invalidate line it will make the points to be like blinking.
what i want is to create a loading effect animation.

the result as the code now is still 3 points, and i want to animate them like in the link.

243189-points1.jpg

something like this :

https://www.bing.com/images/search?view=detailV2&ccid=8KW2mRlu&id=2B3DD82CEF9C3ED45D9FD7BA46D1D1C1E44EA110&thid=OIP.8KW2mRluqOT5e0IvqPrGawHaFj&mediaurl=https%3a%2f%2ffantasydata.com%2fassets%2fimages%2floading-dots.gif&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.f0a5b699196ea8e4f97b422fa8fac66b%3frik%3dEKFO5MHR0Ua61w%26pid%3dImgRaw%26r%3d0&exph=600&expw=800&q=Loading+Dots+Animation&simid=608049150611506477&FORM=IRPRST&ck=B497533834C14185A9F54E79EAA24244&selectedIndex=1&ajaxhist=0&ajaxserp=0

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,873 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,648 questions
0 comments No comments
{count} vote

Accepted answer
  1. Reza Aghaei 4,946 Reputation points MVP
    2022-09-21T03:02:27.77+00:00

    Animation is result of redrawing your model in an interval; and in each interval applying some changes, like change of the color for a blink effect, or change of location or size for a move or grow or shrink effect.

    In a loading example like what you shared in your question, the animation is result of changing the active circle in the interval and drawing active circle with different color. So, you need a timer, set the interval and in the timer increment the active circle index and call Invalidate to raise paint. Then in the paint event, draw all circles, but the one which is active, should be in different color. In the next interval, active index will move, and after a redraw it looks like the active circle is moving:

    243244-loading.gif

    Here is the code:

    using System;  
    using System.Drawing;  
    using System.Windows.Forms;  
    public class LoadingDotsControl : Control  
    {  
        private Timer timer;  
        public LoadingDotsControl()  
        {  
            timer = new Timer();  
            timer.Interval = 300;  
            timer.Tick += Timer_Tick;  
            timer.Enabled = true;  
            DoubleBuffered = true;  
            ResizeRedraw = true;  
        }  
        int count = 5;  
        int active = 0;  
        private void Timer_Tick(object sender, EventArgs e)  
        {  
            Invalidate();  
            active = (active + 1) % count;  
        }  
        protected override void OnPaint(PaintEventArgs e)  
        {  
            e.Graphics.Clear(BackColor);  
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;  
            var w = this.Width / count;  
            var h = this.Height / 2;  
            var padding = w / 8;  
            for (int i = 0; i < count; i++)  
            {  
                var rect = new Rectangle(i * w, h - w / 2, w, w);  
                var brush = active == i? Brushes.RoyalBlue: Brushes.SkyBlue;  
                rect.Inflate(-padding, -padding);  
                e.Graphics.FillEllipse(brush, rect);  
            }  
            base.OnPaint(e);  
        }  
        protected override void Dispose(bool disposing)  
        {  
            if (disposing && (timer != null))  
            {  
                timer.Dispose();  
            }  
            base.Dispose(disposing);  
        }  
    }   
    

    If you want to see more examples, take a look at my post here:

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful