【问题标题】:Animated GIF in ImageList / TabPageImageList / TabPage 中的动画 GIF
【发布时间】: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 显示为图像?我是否必须对图像进行所有者绘制和动画处理?

【问题讨论】:

    标签: .net winforms animated-gif imagelist


    【解决方案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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-04
        • 2012-08-05
        • 2012-03-23
        • 2014-05-18
        • 2013-11-10
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多