I tried this code but it's showing the last frame. and if i set the frame delay to 1000 then it's waiting one second before showing anything and then show the last frame. it's not playing all the frames from first to last.
I tried to load the animated gif first in a pictureBox but the same behavior.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class AnimatedGifControl : Control
{
private List<Image> frames;
private int currentFrameIndex;
private Timer animationTimer;
[Browsable(true)]
[Category("Behavior")]
[Description("The delay between frames in milliseconds.")]
public int FrameDelay { get; set; } = 100; // Default frame delay
public AnimatedGifControl()
{
frames = new List<Image>();
DoubleBuffered = true;
animationTimer = new Timer();
animationTimer.Tick += OnAnimationTick;
}
public void LoadGif(string gifPath)
{
frames.Clear();
using (Image gifImage = Image.FromFile(gifPath))
{
int frameCount = gifImage.GetFrameCount(FrameDimension.Time);
for (int i = 0; i < frameCount; i++)
{
gifImage.SelectActiveFrame(FrameDimension.Time, i);
frames.Add(new Bitmap(gifImage));
}
}
currentFrameIndex = 0;
if (frames.Count > 0)
{
animationTimer.Interval = FrameDelay;
animationTimer.Start();
}
}
private void OnAnimationTick(object sender, EventArgs e)
{
currentFrameIndex = (currentFrameIndex + 1) % frames.Count;
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (frames.Count > 0)
{
e.Graphics.DrawImage(frames[currentFrameIndex], 0, 0, Width, Height);
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
animationTimer.Dispose();
foreach (var frame in frames)
{
frame.Dispose();
}
}
base.Dispose(disposing);
}
}
OK I found the issue. In Design-Time you have the FrameDelay set:
animatedGifControl1.FrameDelay = 100;
For some reason that prevents setting the Interval here during Run-Time:
public int FrameDelay { get; set; } = 120000;
...
if (frames.Count > 0)
{
animationTimer.Interval = FrameDelay;
animationTimer.Start();
To solve the issue remove the Design-Time code that sets FrameDelay in the InitializeComponent method.
The way I worked this out was putting this in the Tick event:
Debug.WriteLine("Tick:" + DateTime.Now.ToString("o") + "-" + animationTimer.Interval);