走马灯图片轮播控件
作者:互联网
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