GIF动画中的ImageList / TabPage的画中、GIF、TabPage、ImageList

2023-09-06 13:14:53 作者:坠泪

我想显示GIF动画作为标签图像的TabPage

I'd like to show an animated GIF as the tab image on a TabPage.

如果将我的形象的的ImageList 并使用 TabPage.ImageIndex 属性,它只能显示第一框架(和不动画):

If I add my image to an ImageList and use the TabPage.ImageIndex property, it only shows the first frame (and doesn't animate):

ImageList imageList = new ImageList();
imageList.Images.Add(Properties.Resources.my_animated_gif);

tabControl.ImageList = imageList;
tabPage.ImageIndex = 0;

在网上的一些论坛也建议的ImageList 不支持GIF动画。

A few forums on the net also suggest ImageList doesn't support animated GIFs.

有没有一种简单的方法来显示GIF动画作为图像的的TabPage ?我必须所有者绘制和动画的形象呢?

Is there an easy way to display an animated GIF as an image on a TabPage? Do I have to owner-draw and animate the image?

推荐答案

这是一个迟到的答案,但希望有人会从中受益,下面是我做的TabPage的动画形象,我用它来显示一个动画加载图标,这是假定您在资源提取的GIF的框架,其中包括他们。

This is a late answer but hopefully someone will benefit from it, below is what I have done to animate the image in the TabPage, I used it to show an animated loading icon, this assumes that you have extracted the frames of the GIF and included them in the resources.

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
namespace GuiLib
{

public class AnimatedTabControl : TabControl
{

    static int ITEM_WIDTH = 250;
    static int ITEM_HEIGHT = 25;
    static int TIMER_INTERVAL = 80;

    static int ICON_X = 3;
    static int ICON_Y = 3;
    static int ICON_WIDTH = 15;
    static int ICON_HIGHT = 15;

    static int TEXT_X = 50;
    static int TEXT_Y = 6;
    static int TEXT_WIDTH = 200;
    static int TEXT_HIGHT = 15;

    int animationIndex;
    static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

    Bitmap[] animationImages = {new Bitmap(GuiLib.Properties.Resources._0), new Bitmap(GuiLib.Properties.Resources._1),new Bitmap(GuiLib.Properties.Resources._2),
                               new Bitmap(GuiLib.Properties.Resources._3),new Bitmap(GuiLib.Properties.Resources._4),new Bitmap(GuiLib.Properties.Resources._5),
                               new Bitmap(GuiLib.Properties.Resources._6),new Bitmap(GuiLib.Properties.Resources._7)};
    Bitmap animatedimage;

    public AnimatedTabControl()
        : base()
    {            
        this.DrawMode = TabDrawMode.OwnerDrawFixed;
        this.SizeMode = TabSizeMode.Fixed;
        this.ItemSize = new Size(ITEM_WIDTH, ITEM_HEIGHT);
        myTimer.Tick += new EventHandler(TimerEventProcessor);
        myTimer.Interval = TIMER_INTERVAL;
        animationIndex = 0;
    }

    private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
    {
        animationIndex++;

        if (animationIndex >= animationImages.Length)
            animationIndex = 0;

        animatedimage = animationImages[animationIndex];
        AnimateLoadingTabsOrStopIfNonIsLoading();
    }

    private void AnimateLoadingTabsOrStopIfNonIsLoading()
    {
        bool stopRunning = true;
        for (int i = 0; i < this.TabPages.Count; i++)
        {
            if (this.TabPages[i] is LoadingTabPage)
            {
                LoadingTabPage ltp = (LoadingTabPage)this.TabPages[i];

                if (ltp.Loading)
                {
                    stopRunning = false;
                    Rectangle r = GetTabRect(i);
                    this.Invalidate(new Rectangle(r.X + ICON_X, r.Y + ICON_Y, ICON_WIDTH, ICON_HIGHT));
                }
            }
        }

        if (stopRunning)
            myTimer.Stop();
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        Rectangle r = e.Bounds;
        r = GetTabRect(e.Index);

        DrawAnimationImageIfLoading(e, r);
        DrawTabTitle(e, r);
    }

    private void DrawTabTitle(DrawItemEventArgs e, Rectangle r)
    {
        string title = this.TabPages[e.Index].Text;
        StringFormat titleFormat = new StringFormat();
        titleFormat.Trimming = StringTrimming.EllipsisCharacter;
        e.Graphics.DrawString(title, this.Font, Brushes.Black, new RectangleF(r.X + TEXT_X, r.Y + TEXT_Y, TEXT_WIDTH, TEXT_HIGHT), titleFormat);
    }

    private void DrawAnimationImageIfLoading(DrawItemEventArgs e, Rectangle r)
    {
        if (this.TabPages[e.Index] is LoadingTabPage)
        {
            if (((LoadingTabPage)this.TabPages[e.Index]).Loading)
            {
                if (animatedimage != null)
                    e.Graphics.DrawImage(animatedimage, new RectangleF(r.X + ICON_X, r.Y + ICON_Y, ICON_WIDTH, ICON_HIGHT));

                if (!myTimer.Enabled)
                    myTimer.Start();
            }
        }
    }       
}
}

而LoadingTabPage,如下:

And the LoadingTabPage as this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GuiLib
{
/// <summary>
/// A Class to facilitate tab page with animated loading icon.
/// </summary>
public class LoadingTabPage : TabPage
{
    public LoadingTabPage(string s)
        : base(s)
    {
        loading = false;
    }

    public LoadingTabPage()
        : base()
    {
        loading = false;
    }

    private bool loading;

    public bool Loading
    {
        get { return loading; }
        set 
        { 
            loading = value;
            if (this.Parent != null)
            {
                this.Parent.Invalidate();
            }
        }
    }

}

}

的使用将是容易的:

The usage will be easy:

myLoadingTabPage.Loading = true;