Pregunta

Me gustaría mostrar un GIF animado la imagen en una pestaña TabPage como.

Si añado mi imagen a una ImageList y usar la propiedad TabPage.ImageIndex, sólo muestra el primer fotograma (y no animados):

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

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

A los pocos foros en la red también sugieren ImageList no soporta archivos GIF animados.

¿Hay una manera fácil de mostrar un GIF animado como una imagen en un TabPage? ¿Tengo que dibujado por propietario y la animación de la imagen?

¿Fue útil?

Solución

Esta es una respuesta tardía pero es de esperar que alguien se beneficiará de ello, a continuación es lo que he hecho para animar la imagen en el TabPage, lo usé para mostrar un icono de carga de animación, esto supone que se han extraído los marcos de la GIF y los incluyó en los recursos.

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

Y el LoadingTabPage como esto:

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

}

}

El uso será fácil:

myLoadingTabPage.Loading = true;

Otros consejos

Te recomiendo (para una solución libre) usando un trabajador de fondo que se actualiza el icono mediante programación en un bucle (y cheques meteorológicas para detener o continuar). Es un poco complejo, pero creo que usted consigue la idea correcta? = P

ImageCollection que es muy similar y es compatible con GIF.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top