GDI不规则圆弧菜单控件----------WinForm控件开发系列
Posted tlmbem
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDI不规则圆弧菜单控件----------WinForm控件开发系列相关的知识,希望对你有一定的参考价值。
/// <summary> /// 圆弧菜单控件 /// </summary> [ToolboxItem(true)] [DefaultProperty("Items")] [DefaultEvent("RadianMenuItemClick")] [Description("圆弧菜单控件")] public partial class RadianMenuExt : Control public delegate void EventHandler(object sender, RadianMenuItemEventArgs e); private event EventHandler radianMenuItemClick; /// <summary> /// 鱼眼菜单单击事件 /// </summary> [Description("鱼眼菜单单击事件")] public event EventHandler RadianMenuItemClick add this.radianMenuItemClick += value; remove this.radianMenuItemClick -= value; #region private int circleRadius = 50; /// <summary> /// 圆半径 /// </summary> [DefaultValue(50)] [Description("圆半径(默认50)")] public int CircleRadius get return this.circleRadius; set if (this.circleRadius == value || value < 0) return; this.circleRadius = value; this.InitializeRadian(); this.Invalidate(); private int radianOpacity = 150; /// <summary> /// 圆弧透明度 /// </summary> [DefaultValue(150)] [Description("圆弧透明度(默认150)")] public int RadianOpacity get return this.radianOpacity; set if (this.radianOpacity == value || this.radianOpacity < 0 || this.radianOpacity > 255) return; this.radianOpacity = value; this.Invalidate(); private int radianTextOpacity = 220; /// <summary> /// 圆弧文字透明度 /// </summary> [DefaultValue(220)] [Description("圆弧文字透明度(默认220)")] public int RadianTextOpacity get return this.radianTextOpacity; set if (this.radianTextOpacity == value || this.radianTextOpacity < 0 || this.radianTextOpacity > 255) return; this.radianTextOpacity = value; this.Invalidate(); private int radianWidth = 70; /// <summary> /// 圆弧宽度 /// </summary> [DefaultValue(70)] [Description("圆弧宽度(默认70)")] public int RadianWidth get return this.radianWidth; set if (this.radianWidth == value || value < 0) return; this.radianWidth = value; this.InitializeRadian(); this.Invalidate(); private int radianWidthLargen = 20; /// <summary> /// 圆弧宽度放大值 /// </summary> [DefaultValue(20)] [Description("圆弧宽度放大值(默认20)")] public int RadianWidthLargen get return this.radianWidthLargen; set if (this.radianWidthLargen == value || value < 0) return; this.radianWidthLargen = value; this.InitializeRadian(); this.Invalidate(); private int radianLargenTime = 350; /// <summary> /// 圆弧放大缩小动画播放的总时间 /// </summary> [DefaultValue(350)] [Description("圆弧放大缩小动画播放的总时间(默认350毫秒)")] public int RadianLargenTime get return this.radianLargenTime; set if (this.radianLargenTime == value || value < 0) return; this.radianLargenTime = value; for (int i = 0; i < this.Items.Count; i++) this.Items[i].Animation.Options.AllTime = value; private bool radianRotate = false; /// <summary> /// 圆弧是否旋转动画 /// </summary> [DefaultValue(false)] [Description("圆弧旋转动画(默认false)")] public bool RadianRotate get return this.radianRotate; set if (this.radianRotate == value) return; this.radianRotate = value; if (value) this.InitializeRadianAnimation(); else this.UnInitializeRadianAnimation(); private int radianRotateTime = 1000; /// <summary> /// 圆弧旋转动画播放的总时间 /// </summary> [DefaultValue(1000)] [Description("圆弧动画播放的总时间(默认1000毫秒)")] public int RadianRotateTime get return this.radianRotateTime; set if (this.radianRotateTime == value) return; this.radianRotateTime = value; for (int i = 0; i < this.Items.Count; i++) this.Items[i].RadianAnimation.Options.AllTime = value; private RadianMenuItemCollection radianMenuItemCollection; /// <summary> /// 圆弧选项配置列表 /// </summary> [Description("圆弧选项配置列表")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public RadianMenuItemCollection Items get if (this.radianMenuItemCollection == null) this.radianMenuItemCollection = new RadianMenuItemCollection(this); return this.radianMenuItemCollection; protected override Size DefaultSize get return new Size(450, 450); /// <summary> /// 选中圆弧选项 /// </summary> private RadianMenuItem selectedItem = null; #endregion public RadianMenuExt() SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true); InitializeComponent(); protected override void OnPaint(PaintEventArgs e) base.OnPaint(e); Graphics g = e.Graphics; g.TextRenderingHint = TextRenderingHint.AntiAlias; for (int i = 0; i < this.Items.Count; i++) SolidBrush radian_sb = new SolidBrush(Color.FromArgb(this.RadianOpacity, this.Items[i].RadianColor)); g.FillRegion(radian_sb, this.Items[i].RadianRegion); radian_sb.Dispose(); if (!String.IsNullOrWhiteSpace(Items[i].Text))//文本 SolidBrush text_sb = new SolidBrush(Color.FromArgb(this.RadianTextOpacity, this.Items[i].TextColor)); SizeF str_size = g.MeasureString(this.Items[i].Text, this.Items[i].TextFont); if (i == 0)//圆心 str_size = new SizeF(str_size.Width + 2f, str_size.Height + 2f); g.DrawString(this.Items[i].Text, this.Items[i].TextFont, text_sb, new RectangleF(this.Items[i].RadianNowRectF.X + (this.Items[i].RadianNowRectF.Width - str_size.Width) / 2, this.Items[i].RadianNowRectF.Y + (this.Items[i].RadianNowRectF.Height - str_size.Height) / 2, str_size.Width, str_size.Height)); else//圆弧 SizeF ds = new System.Drawing.SizeF(this.Items[i].RadianNowRectF.Width - (this.Items[i].RadianMaxRectF.Width - this.Items[i].RadianNormalRectF.Width) / 2, this.Items[i].RadianNowRectF.Height - (this.Items[i].RadianMaxRectF.Height - this.Items[i].RadianNormalRectF.Height) / 2); double degrees = 1 / ((2 * Math.PI * this.Items[i].RadianNowRectF.Width / 2) / 360);//一度弧长 double angle = degrees * ((str_size.Width / this.Items[i].Text.Length) + 4);//一弧长角度 g.TranslateTransform(this.Width / 2, this.Height / 2);//更改起始坐标 g.RotateTransform(90 + this.Items[i].RadianNowStartAngle);//更改起始角度 for (int j = 0; j < this.Items[i].Text.Length; j++) g.RotateTransform((float)angle); g.DrawString(this.Items[i].Text[j].ToString(), this.Items[i].TextFont, text_sb, 0, -this.Items[i].RadianNowRectF.Height / 2 + str_size.Height / 2); g.RotateTransform((float)((this.Items[i].Text.Length * -angle))); g.RotateTransform(-(90 + this.Items[i].RadianNowStartAngle)); g.TranslateTransform(-this.Width / 2, -this.Height / 2);//更改起始坐标 text_sb.Dispose(); protected override void OnResize(EventArgs e) base.OnResize(e); this.InitializeRadian(); protected override void OnClick(EventArgs e) base.OnClick(e); if (this.selectedItem != null && this.radianMenuItemClick != null) this.radianMenuItemClick(this, new RadianMenuItemEventArgs() Item = this.selectedItem ); /// <summary> /// 鼠标进入离开 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void OnMouseMove(MouseEventArgs e) base.OnMouseMove(e); for (int i = 0; i < this.Items.Count; i++) if (this.Items[i].RadianRegion.IsVisible(e.Location))//鼠标进入 if (this.Items[i].RadianMoveState == MoveState.Leave) this.selectedItem = this.Items[i]; this.Items[i].RadianMoveState = MoveState.EnterAnimation; this.Items[i].Animation.AT = AnimationType.ElasticOut; this.Items[i].Animation.Options.AllTime = this.RadianLargenTime; this.Items[i].Animation.Start(true, this.Items[i].Animation.UsedTime); else//鼠标离开 if (this.Items[i].RadianMoveState == MoveState.Enter || this.Items[i].RadianMoveState == MoveState.EnterAnimation) if (this.selectedItem != null && this.selectedItem.Equals(this.Items[i])) this.selectedItem = null; this.Items[i].RadianMoveState = MoveState.LeaveAnimation; this.Items[i].Animation.AT = AnimationType.BackIn; this.Items[i].Animation.Options.AllTime = this.RadianLargenTime; this.Items[i].Animation.Start(false, this.Items[i].Animation.UsedTime); /// <summary> /// 鼠标离开可视区 /// </summary> /// <param name="e"></param> protected override void OnMouseLeave(EventArgs e) base.OnMouseLeave(e); this.selectedItem = null; /// <summary> /// 缩放动画进行中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Animation_AnimationIng(object sender, AnimationEventArgs e) RadianMenuItem rmi = (RadianMenuItem)e.Data; float w = (float)(rmi.RadianNormalRectF.Width + (rmi.RadianMaxRectF.Width - rmi.RadianNormalRectF.Width) * e.progressTime); float h = (float)(rmi.RadianNormalRectF.Height + (rmi.RadianMaxRectF.Height - rmi.RadianNormalRectF.Height) * e.progressTime); float x = (this.ClientRectangle.Width - w) / 2; float y = (this.ClientRectangle.Height - h) / 2; rmi.RadianNowRectF = new RectangleF(x, y, w, h); float v = (float)((rmi.RadianMaxWidth - rmi.RadianNormalWidth) * e.progressTime); rmi.RadianNowWidth = (int)(rmi.RadianNormalWidth + v); int index = this.Items.IndexOf(rmi); if (index == 0) GraphicsPath gp1 = new GraphicsPath(); gp1.AddEllipse(rmi.RadianNowRectF); Region r = new Region(gp1); rmi.RadianRegion = r; gp1.Dispose(); else GraphicsPath gp1 = new GraphicsPath(); GraphicsPath gp2 = new GraphicsPath(); gp1.AddPie(rmi.RadianNowRectF.X, rmi.RadianNowRectF.Y, rmi.RadianNowRectF.Width, rmi.RadianNowRectF.Height, rmi.RadianNowStartAngle, rmi.RadianSweepAngle); gp2.AddPie(rmi.RadianNowRectF.X + rmi.RadianNowWidth / 2, rmi.RadianNowRectF.Y + rmi.RadianNowWidth / 2, rmi.RadianNowRectF.Width - rmi.RadianNowWidth, rmi.RadianNowRectF.Height - rmi.RadianNowWidth, 0f, 360f); Region r = new Region(gp1); r.Exclude(gp2); rmi.RadianRegion = r; gp1.Dispose(); gp2.Dispose(); this.Invalidate(); /// <summary> /// 缩放动画结束 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Animation_AnimationEnding(object sender, AnimationEventArgs e) RadianMenuItem rmi = (RadianMenuItem)e.Data; if (rmi.RadianMoveState == MoveState.LeaveAnimation) rmi.RadianMoveState = MoveState.Leave; else if (rmi.RadianMoveState == MoveState.EnterAnimation) rmi.RadianMoveState = MoveState.Enter; /// <summary> /// 旋转动画进行中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void RadianAnimation_AnimationIng(object sender, AnimationEventArgs e) RadianMenuItem rmi = (RadianMenuItem)e.Data; if (rmi.RadianMoveState == MoveState.Leave) float original = 0f; if (rmi.RadianRotateValue < 0)//旋转方向 original = rmi.RadianAnimation.Options.Transform < 0 ? rmi.RadianStartAngle : (rmi.RadianStartAngle + rmi.RadianRotateValue); else original = rmi.RadianAnimation.Options.Transform > 0 ? rmi.RadianStartAngle : (rmi.RadianStartAngle + rmi.RadianRotateValue); rmi.RadianNowStartAngle = (int)(original + e.Transform * e.progressTime); GraphicsPath gp1 = new GraphicsPath(); GraphicsPath gp2 = new GraphicsPath(); gp1.AddPie(rmi.RadianNormalRectF.X, rmi.RadianNormalRectF.Y, rmi.RadianNormalRectF.Width, rmi.RadianNormalRectF.Height, rmi.RadianNowStartAngle, rmi.RadianSweepAngle); gp2.AddPie(rmi.RadianNormalRectF.X + rmi.RadianNormalWidth / 2, rmi.RadianNormalRectF.Y + rmi.RadianNormalWidth / 2, rmi.RadianNormalRectF.Width - rmi.RadianNormalWidth, rmi.RadianNormalRectF.Height - rmi.RadianNormalWidth, 0f, 360f); Region r = new Region(gp1); r.Exclude(gp2); rmi.RadianRegion = r; gp1.Dispose(); gp2.Dispose(); this.Invalidate(); /// <summary> /// 旋转动画间隔重复事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void RadianAnimation_AnimationRepetitioning(object sender, AnimationEventArgs e) RadianMenuItem rmi = (RadianMenuItem)e.Data; rmi.RadianAnimation.Options.Transform = -1 * rmi.RadianAnimation.Options.Transform; /// <summary> /// 初始化圆弧控件大小位置 /// </summary> private void InitializeRadian() int diameter = this.CircleRadius * 2;//直径 for (int i = 0; i < this.Items.Count; i++) if (i == 0) float w = diameter; float h = diameter; float x = (this.ClientRectangle.Width - w) / 2; float y = (this.ClientRectangle.Height - h) / 2; float max_w = w + this.RadianWidthLargen; float max_h = h + this.RadianWidthLargen; float max_x = (this.ClientRectangle.Width - max_w) / 2; float max_y = (this.ClientRectangle.Height - max_h) / 2; this.Items[i].RadianNormalRectF = new RectangleF(x, y, w, h); this.Items[i].RadianMaxRectF = new RectangleF(max_x, max_y, max_w, max_h); this.Items[i].RadianNowRectF = this.Items[i].RadianNormalRectF; GraphicsPath gp1 = new GraphicsPath(); gp1.AddEllipse(this.Items[i].RadianNormalRectF); Region r = new Region(gp1); this.Items[i].RadianRegion = r; gp1.Dispose(); else float w = diameter + this.RadianWidth * i; float h = diameter + this.RadianWidth * i; float x = (this.ClientRectangle.Width - w) / 2; float y = (this.ClientRectangle.Height - h) / 2; float max_w = w + this.RadianWidthLargen; float max_h = h + this.RadianWidthLargen; float max_x = (this.ClientRectangle.Width - max_w) / 2; float max_y = (this.ClientRectangle.Height - max_h) / 2; this.Items[i].RadianNormalRectF = new RectangleF(x, y, w, h); this.Items[i].RadianMaxRectF = new RectangleF(max_x, max_y, max_w, max_h); this.Items[i].RadianNowRectF = this.Items[i].RadianNormalRectF; this.Items[i].RadianNormalWidth = this.RadianWidth; this.Items[i].RadianMaxWidth = this.RadianWidth + this.RadianWidthLargen; this.Items[i].RadianNowWidth = this.RadianWidth; this.Items[i].RadianNowStartAngle = this.Items[i].RadianStartAngle; GraphicsPath gp1 = new GraphicsPath(); GraphicsPath gp2 = new GraphicsPath(); gp1.AddPie(this.Items[i].RadianNormalRectF.X, this.Items[i].RadianNormalRectF.Y, this.Items[i].RadianNormalRectF.Width, this.Items[i].RadianNormalRectF.Height, this.Items[i].RadianNowStartAngle, this.Items[i].RadianSweepAngle); gp2.AddPie(this.Items[i].RadianNormalRectF.X + this.Items[i].RadianNormalWidth / 2, this.Items[i].RadianNormalRectF.Y + this.Items[i].RadianNormalWidth / 2, this.Items[i].RadianNormalRectF.Width - this.Items[i].RadianNormalWidth, this.Items[i].RadianNormalRectF.Height - this.Items[i].RadianNormalWidth, 0f, 360f); Region r = new Region(gp1); r.Exclude(gp2); this.Items[i].RadianRegion = r; gp1.Dispose(); gp2.Dispose(); if (this.Items[i].Animation == null) this.Items[i].Animation = new AnimationTimer(this, new AnimationOptions()); this.Items[i].Animation.Options.Data = this.Items[i]; this.Items[i].Animation.AnimationIng += new AnimationTimer.AnimationHandel(this.Animation_AnimationIng); this.Items[i].Animation.AnimationEnding += new AnimationTimer.AnimationHandel(this.Animation_AnimationEnding); /// <summary> /// 加载旋转动画 /// </summary> private void InitializeRadianAnimation() for (int i = 1; i < this.Items.Count; i++) if (this.Items[i].RadianRotateValue != 0) this.Items[i].RadianAnimation = new AnimationTimer(this, new AnimationOptions()); this.Items[i].RadianAnimation.AnimationIng += new AnimationTimer.AnimationHandel(this.RadianAnimation_AnimationIng); this.Items[i].RadianAnimation.AnimationRepetitioning += new AnimationTimer.AnimationHandel(this.RadianAnimation_AnimationRepetitioning); this.Items[i].RadianAnimation.Options.AlwaysRepetitionExercise = true; this.Items[i].RadianAnimation.Options.Data = this.Items[i]; this.Items[i].RadianAnimation.Options.Transform = this.Items[i].RadianRotateValue; this.Items[i].RadianAnimation.Options.AllTime = this.RadianRotateTime; this.Items[i].RadianAnimation.AT = AnimationType.UniformMotion; this.Items[i].RadianAnimation.Start(true, 0); /// <summary> /// 卸载旋转动画 /// </summary> private void UnInitializeRadianAnimation() for (int i = 1; i < this.Items.Count; i++) if (this.Items[i].RadianRotateValue != 0) this.Items[i].RadianAnimation.Dispose(); this.Items[i].RadianAnimation = null; protected override void Dispose(bool disposing) if (disposing && (components != null)) components.Dispose(); for (int i = 0; i < this.Items.Count; i++) if (this.Items[i].Animation != null) this.Items[i].Animation.Dispose(); if (this.Items[i].RadianAnimation != null) this.Items[i].RadianAnimation.Dispose(); base.Dispose(disposing); /// <summary> /// 圆弧选项集合 /// </summary> [Description("圆弧选项集合")] [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))] public sealed class RadianMenuItemCollection : IList, ICollection, IEnumerable private ArrayList radianMenuItemList = new ArrayList(); private RadianMenuExt owner; public RadianMenuItemCollection(RadianMenuExt owner) this.owner = owner; #region IEnumerable public IEnumerator GetEnumerator() RadianMenuItem[] listArray = new RadianMenuItem[this.radianMenuItemList.Count]; for (int index = 0; index < listArray.Length; ++index) listArray[index] = (RadianMenuItem)this.radianMenuItemList[index]; return listArray.GetEnumerator(); #endregion #region ICollection public void CopyTo(Array array, int index) for (int i = 0; i < this.Count; i++) array.SetValue(this.radianMenuItemList[i], i + index); public int Count get return this.radianMenuItemList.Count; public bool IsSynchronized get return false; public object SyncRoot get return (object)this; #endregion #region IList public int Add(object value) RadianMenuItem radianMenuItem = (RadianMenuItem)value; this.radianMenuItemList.Add(radianMenuItem); this.owner.InitializeRadian(); this.owner.Invalidate(); return this.Count - 1; public void Clear() for (int i = 0; i < this.Count; i++) RadianMenuItem item = (RadianMenuItem)this.radianMenuItemList[i]; item.Animation.Dispose(); item.Animation = null; item.RadianAnimation.Dispose(); item.RadianAnimation = null; item.RadianRegion.Dispose(); item.TextFont.Dispose(); this.radianMenuItemList.Clear(); this.owner.InitializeRadian(); this.owner.Invalidate(); public bool Contains(object value) return this.IndexOf(value) != -1; public int IndexOf(object value) return this.radianMenuItemList.IndexOf(value); 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) if (!(value is RadianMenuItem)) return; RadianMenuItem item = (RadianMenuItem)value; item.Animation.Dispose(); item.Animation = null; item.RadianAnimation.Dispose(); item.RadianAnimation = null; item.RadianRegion.Dispose(); item.TextFont.Dispose(); this.radianMenuItemList.Remove((RadianMenuItem)value); this.owner.InitializeRadian(); this.owner.Invalidate(); public void RemoveAt(int index) RadianMenuItem item = (RadianMenuItem)this.radianMenuItemList[index]; item.Animation.Dispose(); item.Animation = null; item.RadianAnimation.Dispose(); item.RadianAnimation = null; item.RadianRegion.Dispose(); item.TextFont.Dispose(); this.radianMenuItemList.RemoveAt(index); this.owner.InitializeRadian(); this.owner.Invalidate(); public RadianMenuItem this[int index] get return (RadianMenuItem)this.radianMenuItemList[index]; set this.radianMenuItemList[index] = (RadianMenuItem)value; this.owner.InitializeRadian(); this.owner.Invalidate(); object IList.this[int index] get return (object)this.radianMenuItemList[index]; set this.radianMenuItemList[index] = (RadianMenuItem)value; this.owner.InitializeRadian(); this.owner.Invalidate(); #endregion /// <summary> /// 圆弧选项 /// </summary> [Description("圆弧选项")] public class RadianMenuItem private AnimationTimer animation = null; /// <summary> /// 缩放动画对象 /// </summary> [Browsable(false)] [DefaultValue(null)] [Description("缩放动画对象")] public AnimationTimer Animation get return this.animation; set if (this.animation == value) return; this.animation = value; private AnimationTimer radianAnimation = null; /// <summary> /// 旋转动画对象 /// </summary> [Browsable(false)] [DefaultValue(null)] [Description("旋转动画对象")] public AnimationTimer RadianAnimation get return this.radianAnimation; set if (this.radianAnimation == value) return; this.radianAnimation = value; private RectangleF radianNormalRectF; /// <summary> /// 圆弧选项默认Rect /// </summary> [Browsable(false)] [Description("圆弧选项默认Rect")] public RectangleF RadianNormalRectF get return this.radianNormalRectF; set if (this.radianNormalRectF == value) return; this.radianNormalRectF = value; private RectangleF radianMaxRectF; /// <summary> /// 圆弧选项最大Rect /// </summary> [Browsable(false)] [Description("圆弧选项最大Rect")] public RectangleF RadianMaxRectF get return this.radianMaxRectF; set if (this.radianMaxRectF == value) return; this.radianMaxRectF = value; private RectangleF radianNowRectF; /// <summary> /// 圆弧选项当前Rect /// </summary> [Browsable(false)] [Description("圆弧选项当前Rect")] public RectangleF RadianNowRectF get return this.radianNowRectF; set if (this.radianNowRectF == value) return; this.radianNowRectF = value; private Region radianRegion = new Region(); /// <summary> /// 圆弧选项Region /// </summary> [Browsable(false)] [Description("圆弧选项Region")] public Region RadianRegion get return this.radianRegion; set if (this.radianRegion == value) return; this.radianRegion = value; private MoveState radianMoveState = MoveState.Leave; /// <summary> /// 圆弧选项鼠标状态 /// </summary> [Browsable(false)] [Description("圆弧选项鼠标状态")] public MoveState RadianMoveState get return this.radianMoveState; set if (this.radianMoveState == value) return; this.radianMoveState = value; private string text; /// <summary> /// 圆弧选项文本 /// </summary> [Browsable(true)] [Description("圆弧选项文本")] public string Text get return this.text; set if (this.text == value) return; this.text = value; private Font textFont = new Font("幼圆", 12, FontStyle.Bold); /// <summary> /// 文本字体 /// </summary> [Browsable(true)] [DefaultValue(typeof(Font), "幼圆, 12pt, style=Bold")] [Description("文本字体")] public Font TextFont get return this.textFont; set if (this.textFont == value) return; this.textFont = value; private Color textColor = Color.White; /// <summary> /// 文本字体颜色 /// </summary> [Browsable(true)] [DefaultValue(typeof(Color), "White")] [Description("文本字体颜色")] public Color TextColor get return this.textColor; set if (this.textColor == value) return; this.textColor = value; private Color radianColor = Color.Empty; /// <summary> /// 圆弧颜色 /// </summary> [Browsable(true)] [DefaultValue(typeof(Color), "Empty")] [Description("圆弧颜色")] public Color RadianColor get return this.radianColor; set if (this.radianColor == value) return; this.radianColor = value; private float radianStartAngle = 0f; /// <summary> /// 圆弧开始角度 /// </summary> [Browsable(true)] [DefaultValue(0f)] [Description("圆弧开始角度")] public float RadianStartAngle get return this.radianStartAngle; set if (this.radianStartAngle == value || value < -360 || value > 360) return; this.radianStartAngle = value; private float radianSweepAngle = 90f; /// <summary> /// 圆弧从 RadianStartAngle 参数到圆弧的结束点沿顺时针方向度量的角(以度为单位)。 /// </summary> [Browsable(true)] [DefaultValue(90f)] [Description("圆弧从 RadianStartAngle 参数到圆弧的结束点沿顺时针方向度量的角(以度为单位)。")] public float RadianSweepAngle get return this.radianSweepAngle; set if (this.radianSweepAngle == value || value < -360 || value > 360) return; this.radianSweepAngle = value; private int radianRotateValue = 0; /// <summary> /// 圆弧要旋转的角度(-180至180) /// </summary> [Browsable(true)] [DefaultValue(0)] [Description("弧度要旋转的角度(-180至180)(默认0)")] public int RadianRotateValue get return this.radianRotateValue; set if (this.radianRotateValue == value || value < -180 || value > 180) return; this.radianRotateValue = value; private float radianNowStartAngle; /// <summary> /// 当前圆弧开始角度 /// </summary> [Browsable(false)] [Description("当前圆弧开始角度")] public float RadianNowStartAngle get return this.radianNowStartAngle; set if (this.radianNowStartAngle == value || value < -360 || value > 360) return; this.radianNowStartAngle = value; private int radianNormalWidth; /// <summary> /// 圆弧默认宽度 /// </summary> [Browsable(false)] [Description("圆弧默认宽度")] public int RadianNormalWidth get return this.radianNormalWidth; set if (this.radianNormalWidth == value) return; this.radianNormalWidth = value; private int radianMaxWidth; /// <summary> /// 圆弧最大宽度 /// </summary> [Browsable(false)] [Description("圆弧最大宽度")] public int RadianMaxWidth get return this.radianMaxWidth; set if (this.radianMaxWidth == value) return; this.radianMaxWidth = value; private int radianNowWidth; /// <summary> /// 当前圆弧宽度 /// </summary> [Browsable(false)] [Description("当前圆弧宽度")] public int RadianNowWidth get return this.radianNowWidth; set if (this.radianNowWidth == value) return; this.radianNowWidth = value; /// <summary> /// 圆弧选项鼠标状态 /// </summary> [Description("圆弧选项鼠标状态")] public enum MoveState /// <summary> /// 光标已离开可视区 /// </summary> Leave, /// <summary> /// 光标已离开可视区(动画还在进行中) /// </summary> LeaveAnimation, /// <summary> /// 光标已进入可视区 /// </summary> Enter, /// <summary> /// 光标已进入可视区(动画还在进行中) /// </summary> EnterAnimation /// <summary> /// 圆弧选项单击事件参数 /// </summary> [Description("鱼眼菜单单击事件参数")] public class RadianMenuItemEventArgs : EventArgs /// <summary> /// 鱼眼菜单选项 /// </summary> [Description("鱼眼菜单选项")] public RadianMenuExt.RadianMenuItem Item get; set;
源码下载:GDI不规则圆弧菜单控件.zip
以上是关于GDI不规则圆弧菜单控件----------WinForm控件开发系列的主要内容,如果未能解决你的问题,请参考以下文章
求教:C#中winform 并未使用任何图片,但报错”GDI+ 中发生一般性错误“