/// <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 onm ouseMove(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 onm ouseLeave(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