其他分享
首页 > 其他分享> > 走马灯图片轮播控件

走马灯图片轮播控件

作者:互联网

  public partial class ImageCarouselExt : Control
  {

    #region

    private bool barShow = true;
    /// <summary>
    ///是否显示导航栏 
    /// </summary>
    [DefaultValue(true)]
    [Description("是否显示导航栏")]
    public bool BarShow
    {
      get { return this.barShow; }
      set
      {
        if (this.barShow == value)
          return;
        this.barShow = value;
        this.Invalidate();
      }
    }

    private Color barNormalColor = Color.Gray;
    /// <summary>
    ///导航栏正常颜色 
    /// </summary>
    [DefaultValue(typeof(Color), "Gray")]
    [Description("导航栏正常颜色")]
    public Color BarNormalColor
    {
      get { return this.barNormalColor; }
      set
      {
        if (this.barNormalColor == value)
          return;
        this.barNormalColor = value;
        this.Invalidate();
      }
    }

    private Color barCurrentColor = Color.Tomato;
    /// <summary>
    ///导航栏当前颜色 
    /// </summary>
    [DefaultValue(typeof(Color), "Tomato")]
    [Description("导航栏当前颜色")]
    public Color BarCurrentColor
    {
      get { return this.barCurrentColor; }
      set
      {
        if (this.barCurrentColor == value)
          return;
        this.barCurrentColor = value;
        this.Invalidate();
      }
    }

    private DisplayImageCollection displayImageCollection;
    /// <summary>
    /// 要播放的图片集合
    /// </summary>
    [DefaultValue(null)]
    [Description("要播放的图片集合")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public DisplayImageCollection Images
    {
      get
      {
        if (this.displayImageCollection == null)
          this.displayImageCollection = new DisplayImageCollection(this);
        return this.displayImageCollection;
      }
    }

    private double animationTime = 500d;
    /// <summary>
    /// 动画播放的总时间
    /// </summary>
    [DefaultValue(500d)]
    [Description("动画播放的总时间(默认500毫秒)")]
    public double AnimationTime
    {
      get { return this.animationTime; }
      set
      {
        if (this.animationTime == value)
          return;
        this.animationTime = value;
      }
    }

    private int intervalTime = 1000;
    /// <summary>
    /// 图片轮播的时间间隔
    /// </summary>
    [DefaultValue(1000)]
    [Description("图片轮播的时间间隔(默认1000毫秒)")]
    public int IntervalTime
    {
      get { return this.intervalTime; }
      set
      {
        if (this.intervalTime == value)
          return;
        this.intervalTime = value;
      }
    }

    private int imageWidth = 400;
    /// <summary>
    ///图片框宽度 
    /// </summary>
    [DefaultValue(400)]
    [Description("图片框宽度")]
    public int ImageWidth
    {
      get { return this.imageWidth; }
      set
      {
        if (this.imageWidth == value)
          return;
        this.imageWidth = value;
        this.InitializeSlideDirection();
        this.InitializeDisplaySize();
        this.Invalidate();
      }
    }

    private int imageHeight = 200;
    /// <summary>
    ///图片框高度 
    /// </summary>
    [DefaultValue(200)]
    [Description("图片框高度")]
    public int ImageHeight
    {
      get { return this.imageHeight; }
      set
      {
        if (this.imageHeight == value)
          return;
        this.imageHeight = value;
        this.InitializeSlideDirection();
        this.InitializeDisplaySize();
        this.Invalidate();
      }
    }

    private SlideType slideDirection = SlideType.RightToLeft;
    /// <summary>
    ///滑动方向 
    /// </summary>
    [DefaultValue(SlideType.RightToLeft)]
    [Description("滑动方向")]
    public SlideType SlideDirection
    {
      get { return this.slideDirection; }
      set
      {
        if (this.slideDirection == value)
          return;
        this.slideDirection = value;
        this.InitializeSlideDirection();
        this.InitializeDisplaySize();
        this.Invalidate();
      }
    }

    private int imageDisplay = 1;
    /// <summary>
    ///显示区显示图片数量(最小值1)
    /// </summary>
    [DefaultValue(1)]
    [Description("显示区显示图片数量最小值1")]
    public int ImageDisplay
    {
      get { return this.imageDisplay; }
      set
      {
        if (this.imageDisplay == value || value < 1)
          return;
        this.imageDisplay = value;
        this.InitializeImageDisplay();
        this.InitializeDisplaySize();
        this.Invalidate();
      }
    }

    int currentImageIndex = -1;
    /// <summary>
    ///当前图片显示区第一张图片的索引 
    /// </summary>
    [Browsable(false)]
    [DefaultValue(-1)]
    [Description("当前图片显示区第一张图片的索引")]
    public int CurrentImageIndex
    {
      get { return this.currentImageIndex; }
      set
      {
        if (this.currentImageIndex == value)
          return;
        this.currentImageIndex = value;
      }
    }

    /// <summary>
    /// 图片框滑动距离
    /// </summary>
    private int distance = 0;

    /// <summary>
    /// 显示区中所有图片框集合
    /// </summary>
    private List<DisplayRectangleFItem> displayRectangleFItemList;

    /// <summary>
    /// 图片轮播的时间间隔累计(-1为动画正在切换中)
    /// </summary>
    private int intervalTimeValue = 0;

    /// <summary>
    /// 动画播放时间间隔定时器
    /// </summary>
    private Timer intervalTimer;

    /// <summary>
    /// 动画播放定时器
    /// </summary>
    private AnimationTimer animationTimer;

    #endregion

    public ImageCarouselExt()
    {
      SetStyle(ControlStyles.UserPaint, true);
      SetStyle(ControlStyles.AllPaintingInWmPaint, true);
      SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
      SetStyle(ControlStyles.ResizeRedraw, true);
      SetStyle(ControlStyles.SupportsTransparentBackColor, true);
      InitializeComponent();

      this.InitializeImageDisplay();
      this.InitializeSlideDirection();
      this.InitializeDisplaySize();

      this.intervalTimer = new Timer();
      this.intervalTimer.Interval = 50;
      this.intervalTimer.Tick += new EventHandler(this.intervalTimer_Tick);

      this.animationTimer = new AnimationTimer(this, new AnimationOptions());
      this.animationTimer.AnimationIng += new AnimationTimer.AnimationHandel(this.animationTimer_AnimationIng);
      this.animationTimer.AnimationEnding += new AnimationTimer.AnimationHandel(this.animationTimer_AnimationEnding);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
      base.OnPaint(e);

      Graphics g = e.Graphics;
      if (this.Images.Count > 0)
      {
        for (int i = 0; i < this.displayRectangleFItemList.Count; i++)
        {
          if (this.Images[this.displayRectangleFItemList[i].image_index].image != null)
            g.DrawImage(this.Images[this.displayRectangleFItemList[i].image_index].image, this.displayRectangleFItemList[i].current_rectf);
        }
        if (this.BarShow)
        {
          SmoothingMode sm = g.SmoothingMode;
          g.SmoothingMode = SmoothingMode.HighQuality;
          float w = 12;
          float h = 12;
          float interval = 5;
          float sum = (w + interval) * this.Images.Count - interval;
          float start_x = (e.ClipRectangle.Width - sum) / 2;
          float start_y = (e.ClipRectangle.Height - sum) / 2;
          SolidBrush barNormal_sb = new SolidBrush(Color.FromArgb(150, this.BarNormalColor));
          SolidBrush barCurrent_sb = new SolidBrush(Color.FromArgb(150, this.BarCurrentColor));
          for (int i = 0; i < this.Images.Count; i++)
          {
            RectangleF bar_rectf = new RectangleF(start_x + i * w + (i - 1) * interval, e.ClipRectangle.Height - h - 10, w, h);
            if (this.SlideDirection == SlideType.TopToBottom || this.SlideDirection == SlideType.BottomToTop)
            {
              bar_rectf = new RectangleF(e.ClipRectangle.Width - w - 10, start_y + i * h + (i - 1) * interval, w, h);
            }
            g.FillEllipse(i == this.currentImageIndex ? barCurrent_sb : barNormal_sb, bar_rectf);
          }
          barNormal_sb.Dispose();
          barCurrent_sb.Dispose();
          g.SmoothingMode = sm;
        }
       
      }
    }

    /// <summary>
    /// 动画开始事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void intervalTimer_Tick(object sender, EventArgs e)
    {
      if (this.intervalTimeValue == -1)//动画进行中
        return;
      this.intervalTimeValue += this.intervalTimer.Interval;
      if (this.intervalTimeValue >= this.intervalTime)
      {
        this.intervalTimeValue = -1;

        this.InitializeRectangle();

        this.animationTimer.AT = AnimationType.EaseOut;
        this.animationTimer.Options.Transform = this.distance;
        this.animationTimer.Options.AllTime = this.animationTime;
        this.animationTimer.Start(true, 0);
      }
    }

    /// <summary>
    /// 动画进行中事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void animationTimer_AnimationIng(object sender, AnimationEventArgs e)
    {
      float dis = (float)(e.Transform * e.progressTime);//计算动画值
      for (int i = 0; i < this.displayRectangleFItemList.Count; i++)
      {
        RectangleF current_rectf = new RectangleF(this.displayRectangleFItemList[i].v + dis, this.displayRectangleFItemList[i].current_rectf.Y, this.displayRectangleFItemList[i].current_rectf.Width, this.displayRectangleFItemList[i].current_rectf.Height);
        if (this.SlideDirection == SlideType.BottomToTop || this.SlideDirection == SlideType.TopToBottom)
        {
          current_rectf = new RectangleF(this.displayRectangleFItemList[i].current_rectf.X, this.displayRectangleFItemList[i].v + dis, this.displayRectangleFItemList[i].current_rectf.Width, this.displayRectangleFItemList[i].current_rectf.Height);
        }
        this.displayRectangleFItemList[i].current_rectf = current_rectf;
      }
      this.Invalidate();
    }

    /// <summary>
    /// 动画结束时事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void animationTimer_AnimationEnding(object sender, AnimationEventArgs e)
    {
      //动画结束时当前图片索引要移动
      if (this.SlideDirection == SlideType.RightToLeft || this.SlideDirection == SlideType.BottomToTop)
      {
        this.currentImageIndex += 1;
        if (this.currentImageIndex > this.Images.Count - 1)
          this.currentImageIndex = 0;
      }
      else
      {
        this.currentImageIndex -= 1;
        if (this.currentImageIndex < 0)
          this.currentImageIndex = this.Images.Count - 1; ;
      }

      this.intervalTimeValue = 0;
    }

    /// <summary>
    /// 初始化图片显示区大小
    /// </summary>
    private void InitializeDisplaySize()
    {
      if (this.SlideDirection == SlideType.RightToLeft || this.SlideDirection == SlideType.LeftToRight)
      {
        this.SetClientSizeCore(this.ImageWidth * this.ImageDisplay, this.ImageHeight);
      }
      else
      {
        this.SetClientSizeCore(this.ImageWidth, this.ImageHeight * this.ImageDisplay);
      }
    }

    /// <summary>
    /// 初始化图片框滑动距离
    /// </summary>
    private void InitializeSlideDirection()
    {
      switch (this.SlideDirection)
      {
        case SlideType.RightToLeft:
          {
            this.distance = -this.ImageWidth;
            break;
          }
        case SlideType.LeftToRight:
          {
            this.distance = this.ImageWidth;
            break;
          }
        case SlideType.BottomToTop:
          {
            this.distance = -this.ImageHeight;
            break;
          }
        case SlideType.TopToBottom:
          {
            this.distance = this.ImageHeight;
            break;
          }
      }

    }

    /// <summary>
    /// 初始化第一次播放时第一个图片框的图片索引
    /// </summary>
    private void InitializeCurrentIndex()
    {
      if (this.currentImageIndex != -1)
        return;
      if (this.SlideDirection == SlideType.RightToLeft || this.SlideDirection == SlideType.BottomToTop)
      {
        this.currentImageIndex = 0;
      }
      else
      {
        this.currentImageIndex = this.Images.Count - 1;
      }
    }

    /// <summary>
    /// 初始化滑动时要滑动的图片框数量
    /// </summary>
    private void InitializeImageDisplay()
    {
      this.displayRectangleFItemList = new List<DisplayRectangleFItem>();
      for (int i = 0; i < this.ImageDisplay + 1; i++)
      {
        displayRectangleFItemList.Add(new DisplayRectangleFItem());
      }
    }

    /// <summary>
    /// 初始化播放前每一个图片框的信息
    /// </summary>
    private void InitializeRectangle()
    {
      this.InitializeCurrentIndex();

      if (this.SlideDirection == SlideType.RightToLeft || this.SlideDirection == SlideType.BottomToTop)
      {
        for (int i = 0; i < this.displayRectangleFItemList.Count; i++)
        {
          this.displayRectangleFItemList[i].v = i * -this.distance;
          if (this.SlideDirection == SlideType.RightToLeft)
          {
            this.displayRectangleFItemList[i].current_rectf = new RectangleF(this.displayRectangleFItemList[i].v, 0, this.ImageWidth, this.ImageHeight);
          }
          else
          {
            this.displayRectangleFItemList[i].current_rectf = new RectangleF(0, this.displayRectangleFItemList[i].v, this.ImageWidth, this.ImageHeight);
          }
          this.displayRectangleFItemList[i].image_index = this.currentImageIndex + i;
          while (this.displayRectangleFItemList[i].image_index > this.Images.Count - 1)
          {
            this.displayRectangleFItemList[i].image_index -= this.Images.Count;
          }
        }
      }
      else
      {
        for (int i = this.displayRectangleFItemList.Count - 1; i >= 0; i--)
        {
          this.displayRectangleFItemList[i].v = (i == 0) ? -this.distance : (i - 1) * this.distance;
          if (this.SlideDirection == SlideType.LeftToRight)
          {
            this.displayRectangleFItemList[i].current_rectf = new RectangleF(this.displayRectangleFItemList[i].v, 0, this.ImageWidth, this.ImageHeight);
          }
          else
          {
            this.displayRectangleFItemList[i].current_rectf = new RectangleF(0, this.displayRectangleFItemList[i].v, this.ImageWidth, this.ImageHeight);
          }
          this.displayRectangleFItemList[i].image_index = this.currentImageIndex - (this.displayRectangleFItemList.Count - 1 - i);
          while (this.displayRectangleFItemList[i].image_index < 0)
          {
            this.displayRectangleFItemList[i].image_index += this.Images.Count;
          }
        }
      }
    }

    /// <summary>
    /// 开始轮播图片
    /// </summary>
    public void Play()
    {
      this.intervalTimer.Enabled = true;
    }

    /// <summary>
    /// 停止轮播图片
    /// </summary>
    public void Stop()
    {
      this.intervalTimer.Enabled = false;
    }

    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
        if (this.intervalTimer != null)
        {
          this.intervalTimer.Dispose();
        }
        if (this.animationTimer != null)
        {
          this.animationTimer.Dispose();
        }
      }
      base.Dispose(disposing);
    }

    /// <summary>
    /// 鱼眼菜单选项集合
    /// </summary>
    [Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
    public sealed class DisplayImageCollection : IList, ICollection, IEnumerable
    {
      private ArrayList fisheyeItemList = new ArrayList();
      private ImageCarouselExt owner;

      public DisplayImageCollection(ImageCarouselExt owner)
      {
        this.owner = owner;
      }

      #region IEnumerable

      public IEnumerator GetEnumerator()
      {
        DisplayImage[] listArray = new DisplayImage[this.fisheyeItemList.Count];
        for (int index = 0; index < listArray.Length; ++index)
          listArray[index] = (DisplayImage)this.fisheyeItemList[index];
        return listArray.GetEnumerator();
      }

      #endregion

      #region ICollection

      public void CopyTo(Array array, int index)
      {
        throw new NotImplementedException();
      }

      public int Count
      {
        get
        {
          return this.fisheyeItemList.Count;
        }
      }

      public bool IsSynchronized
      {
        get
        {
          return false;
        }
      }

      public object SyncRoot
      {
        get
        {
          return (object)this;
        }
      }

      #endregion

      #region IList

      public int Add(object value)
      {
        DisplayImage fisheyeItem = (DisplayImage)value;
        this.fisheyeItemList.Add(fisheyeItem);
        this.owner.Invalidate();
        return this.Count - 1;
      }

      public void Clear()
      {
        this.fisheyeItemList.Clear();
        this.owner.Invalidate();
      }

      public bool Contains(object value)
      {
        throw new NotImplementedException();
      }

      public int IndexOf(object value)
      {
        return this.IndexOf((DisplayImage)value);
        return -1;
      }

      public void Insert(int index, object value)
      {
        throw new NotImplementedException();
      }

      public bool IsFixedSize
      {
        get { return false; }
      }

      public bool IsReadOnly
      {
        get { return false; }
      }

      public void Remove(object value)
      {
        this.fisheyeItemList.Remove((DisplayImage)value);
        this.owner.Invalidate();
      }

      public void RemoveAt(int index)
      {
        this.fisheyeItemList.RemoveAt(index);
        this.owner.Invalidate();
      }

      public DisplayImage this[int index]
      {
        get
        {
          if (index > this.Count - 1)
            return null;
          return (DisplayImage)this.fisheyeItemList[index];
        }
        set
        {
          this.fisheyeItemList[index] = (DisplayImage)value;
          this.owner.Invalidate();
        }
      }

      object IList.this[int index]
      {
        get
        {
          return (object)this.fisheyeItemList[index];
        }
        set
        {
          this.fisheyeItemList[index] = (DisplayImage)value;
          this.owner.Invalidate();
        }
      }

      #endregion

    }

    /// <summary>
    /// 显示区图片
    /// </summary>
    [Description("显示区图片")]
    public class DisplayImage
    {
      /// <summary>
      /// 图片
      /// </summary>
      [Description("图片")]
      public Image image { get; set; }
    }

    /// <summary>
    /// 滑动方向
    /// </summary>
    [Description("滑动方向")]
    public enum SlideType
    {
      /// <summary>
      /// 由右往左
      /// </summary>
      RightToLeft,
      /// <summary>
      /// 由左往右
      /// </summary>
      LeftToRight,
      /// <summary>
      /// 由下往上
      /// </summary>
      BottomToTop,
      /// <summary>
      /// 由上往下
      /// </summary>
      TopToBottom
    }

    /// <summary>
    /// 显示区rectf选项
    /// </summary>
    [Description("显示区rectf选项")]
    public class DisplayRectangleFItem
    {
      /// <summary>
      /// 运动前坐标
      /// </summary>
      [Description("运动前坐标")]
      public float v { get; set; }

      /// <summary>
      /// 当前rectf
      /// </summary>
      [Description("当前rectf")]
      public RectangleF current_rectf { get; set; }

      /// <summary>
      /// rectf对应指定Images中索引的Image
      /// </summary>
      [Description("rectf对应指定Images中索引的Image")]
      public int image_index { get; set; }
    }
 
 }

 源码下载:CSharp走马灯图片轮播控件.zip

标签:控件,return,轮播,index,int,value,public,走马灯,displayRectangleFItemList
来源: https://www.cnblogs.com/tlmbem/p/11331389.html