ImageList / TabPage 中的动画 GIF

Posted

技术标签:

【中文标题】ImageList / TabPage 中的动画 GIF【英文标题】:Animated GIF in ImageList / TabPage 【发布时间】:2010-10-22 05:22:36 【问题描述】:

我想在TabPage 上显示一个动画 GIF 作为标签图像。

如果我将我的图像添加到ImageList 并使用TabPage.ImageIndex 属性,它只会显示第一帧(并且不会动画):

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

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

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

有没有一种简单的方法可以在TabPage 上将动画 GIF 显示为图像?我是否必须对图像进行所有者绘制和动画处理?

【问题讨论】:

【参考方案1】:

这是一个较晚的答案,但希望有人会从中受益,以下是我为 TabPage 中的图像制作动画所做的,我用它来显示动画加载图标,这假设您已经提取了GIF 并将它们包含在资源中。

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 是这样的:

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();
            
        
    




使用会很简单:

myLoadingTabPage.Loading = true;

【讨论】:

正如我所想,唯一的解决方案是所有者绘制。不过能得到一些参考代码还是不错的,希望以后能对大家有所帮助。【参考方案2】:

我建议(对于免费解决方案)使用后台工作程序,它以编程方式循环更新图标(并检查天气以停止或继续)。这有点复杂,但我认为你的想法对吗? =P

【讨论】:

【参考方案3】:

Devexpress 有一个非常相似的ImageCollection,它支持 GIF。

【讨论】:

以上是关于ImageList / TabPage 中的动画 GIF的主要内容,如果未能解决你的问题,请参考以下文章

winform如何让动态创建的tabPage优先显示

C# winform- 选择卡问题 : 想要通过单击Tabpage A 中的按钮实现 转换到Tabpage B 中,请问如何实现?

c#.请问如何给tancontrol中的tabpage添加一个关闭事件,让在关闭tabpage时发生该事件。。

以编程方式选择 TabControl 中的现有 TabPage 会显示一个空白页

如何清除嵌套在 TabControl、TabPage 和 2 个面板中的文本框?

如何根据ListView中的数据打开某个TabPage?