PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框

零.引言

  PropertyGrid中我们经常看到一些下拉式的编辑方式(Color属性)和弹出式编辑框(字体),这些都是为一些复杂的属性提供的编辑方式,本文主要说明如何实现这样的编辑方式。

一.为属性提供编辑类

  弹出式和下拉式是如何实现的呢,这需要为属性提供一个专门的编辑类。.Net为我们提供了一个System.Drawing.Design.UITypeEditor类,它是所有编辑类的基类,从他继承出了诸如ColorEditor、FontEditor的类,因此我们可以在属性框中编辑颜色和字体。定义了这样的类,我们也可以为自己的属性实现弹出式和下拉式编辑方式。

  先看一下MSDN中对UITypeEditor的介绍:提供可用于设计值编辑器的基类,这些编辑器可提供用户界面 (UI),用来表示和编辑所支持的数据类型的对象值。

  UITypeEditor 类提供一种基类,可以从该基类派生和进行扩展,以便为设计时环境实现自定义类型编辑器。通常,您的自定义类型编辑器与 PropertyGrid 控件进行交互。在文本框值编辑器不足以有效地选择某些类型的值的情况下,自定义类型编辑器非常有用。

  继承者说明:

  若要实现自定义设计时 UI 类型编辑器,必须执行下列步骤:

  • 定义一个从 UITypeEditor 派生的类。
  • 重写 EditValue 方法以处理用户界面、用户输入操作以及值的分配。
  • 重写 GetEditStyle 方法,以便将编辑器将使用的编辑器样式的类型通知给“属性”窗口。

  通过执行下列步骤,可以为在“属性”窗口中绘制值的表示形式添加附加支持:

  • 重写 GetPaintValueSupported 方法以指示编辑器支持显示值的表示形式。
  • 重写 PaintValue 方法以实现该值的表示形式的显示。
  • 如果编辑器应具有初始化行为,则重写 UITypeEditor 构造函数方法。

二.下拉式编辑方式

  接下来我们来实现下拉式编辑方式,接下来举一个具体的例子来说明。

  首先假如我们有一个控件类MyControl:

  
 1 public class MyControl : System.Windows.Forms.UserControl

 2 {

 3         private double _angle;

 4 

 5         [BrowsableAttribute(true)]

 6         public double Angle

 7         {

 8             get

 9             { return _angle; }

10             set

11             { _angle = value; }

12         }

13 

14         public MyControl()

15         {

16             this._angle = 90;

17         }

18 

19         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

20         {

21             e.Graphics.DrawString("The Angle is " + _angle, this.Font, Brushes.Red,0,0);

22         }

23 }
View Code

  其中有个属性Angle,我们要为其提供下拉式和弹出式编辑方式,当然了,一般都是较为复杂的属性才需要,这里只是为了举例说明。

  我们为其设计一个编辑类AngleEditor,在第二节中,继承说明中的第一条和第二条,EditValue和GetEditStyle两个函数,这是必须要重写的:

  
  1 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]

  2     public class AngleEditor : System.Drawing.Design.UITypeEditor

  3 {

  4         public AngleEditor()

  5         {

  6         }

  7         //下拉式还是弹出式

  8         public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)

  9         {

 10             return UITypeEditorEditStyle.DropDown;

 11         }

 12 

 13         // 为属性显示UI编辑框

 14         public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)

 15         {

 16             //值类型不为double,直接返回value

 17             if (value.GetType() != typeof(double))

 18                 return value;

 19 

 20             //值为double,显示下拉式或弹出编辑框

 21             IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

 22             if (edSvc != null)

 23             {

 24                 // 显示编辑框并初始化编辑框的值

 25                 AngleControl angleControl = new AngleControl((double)value);

 26                 edSvc.DropDownControl(angleControl);

 27                 // 返回编辑框中编辑的值.

 28                 if (value.GetType() == typeof(double))

 29                     return angleControl.angle;

 30             }

 31             return value;

 32         }

 33 

 34         //下面两个函数是为了在PropertyGrid中显示一个辅助的效果

 35         //可以不用重写

 36         public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)

 37         {

 38             int normalX = (e.Bounds.Width / 2);

 39             int normalY = (e.Bounds.Height / 2);

 40 

 41             e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);

 42             e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);

 43             e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);

 44 

 45             double radians = ((double)e.Value * Math.PI) / (double)180;

 46             e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,

 47                 e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),

 48                 e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));

 49         }

 50 

 51         public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)

 52         {

 53             return true;

 54         }

 55     }

 56 

 57     // 这里是我们要显示出来的编辑器,把它作为一个内置类

 58     //从UserControl继承,要在上面EditValue函数中使用的

 59     internal class AngleControl : System.Windows.Forms.UserControl

 60     {

 61         public double angle; //编辑的角度

 62         private float x;     //鼠标位置

 63         private float y;

 64 

 65         public AngleControl(double initial_angle)

 66         {

 67             this.angle = initial_angle;

 68         }

 69         //显现时,显示属性的当前值

 70         protected override void OnLoad(EventArgs e)

 71         {

 72             int originX = (this.Width / 2);

 73             int originY = (this.Height / 2);

 74             this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);

 75             this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);

 76             base.OnLoad(e);

 77         }

 78 

 79         //绘制控件,用来显示编辑角度

 80         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

 81         {

 82             int originX = (this.Width / 2);

 83             int originY = (this.Height / 2);

 84 

 85             e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);

 86             e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);

 87 

 88             e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);

 89         }

 90         //鼠标移动时设置角度

 91         protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)

 92         {

 93             if (e.Button == MouseButtons.Left)

 94             {

 95                 int originX = (this.Width / 2);

 96                 int originY = (this.Height / 2);

 97                 double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));

 98                 double h = e.Y - originY;

 99                 this.angle = Math.Asin(h / len);

100                 if ((e.X >= originX && e.Y >= originY))

101                 {

102                     this.x = (float)(50 * Math.Cos(this.angle) + originX);

103                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

104                     this.angle = this.angle * 180 / Math.PI;

105                 }

106                 else if (e.X < originX && e.Y > originY)

107                 {

108                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

109                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

110                     this.angle = 180 - this.angle * 180 / Math.PI;

111                 }

112                 else if (e.X < originX && e.Y < originY)

113                 {

114                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

115                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

116                     this.angle = 180 - this.angle * 180 / Math.PI;

117                 }

118                 else if (e.X >= originX && e.Y <= originY)

119                 {

120                     this.x = (float)(originX + 50 * Math.Cos(this.angle));

121                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

122                     this.angle = 360 + this.angle * 180 / Math.PI;

123                 }

124                 this.Invalidate();

125             }

126           

127         }

128       

129 }
View Code

  这里有两个类,一个是AngleEditor,他就是我们要用于到属性特性中的编辑类,一个是AngleControl,他是辅助AngleEditor来编辑属性的,也就是说,他就是一个form,当我们编辑属性时,他会显现出来,供我们编辑属性值,可以是textBox,图形,表格,各种方式,只需要最后他返回编辑好的属性值给AngleEditor类。在AngleEditor类中的EditValue函数中,我们会调用AngleControl类,并接受它返回的值。

  设计好编辑类后,把它应用到MyControl类中的Angle属性中,在Angle属性中增加特性[EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))],相当于告诉PropertyGrid我们要用AngleEditor来编辑这个属性。

  
1         [BrowsableAttribute(true)]

2         [EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))]

3         public double Angle

4         {

5             get

6             { return _angle; }

7             set

8             { _angle = value; }

9         }
View Code

  好了,现在就可以使用下拉框来编辑我们的Angle属性了,效果如下:

  PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框

  上面那个圆圈就是我们用来编辑角度的。

三.弹出式编辑方式

  实现了下拉式,我们来实现弹出式,弹出式和下拉式非常的相像,现在要弹出一个编辑框,因此我们的AngleControl类不能从UserControl继承,而从From继承,让他成为一个对话框,在AngleEditor的EditValue函数中,弹出他并接受返回值,如下:

  
  1 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]

  2     public class AngleEditor : System.Drawing.Design.UITypeEditor

  3 {

  4         public AngleEditor()

  5         {

  6         }

  7         //下拉式还是弹出式

  8         public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)

  9         {

 10             return UITypeEditorEditStyle.Modal;//弹出式

 11         }

 12 

 13         // 为属性显示UI编辑框

 14         public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)

 15         {

 16             //值类型不为double,直接返回value

 17             if (value.GetType() != typeof(double))

 18                 return value;

 19 

 20             //值为double,显示下拉式或弹出编辑框

 21             IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

 22             if (edSvc != null)

 23             {

 24                 // 显示编辑框并初始化编辑框的值

 25                 AngleControl2 angleControl = new AngleControl2((double)value);

 26                 edSvc.ShowDialog(angleControl);                

 27 // 返回编辑框中编辑的值.

 28                 if (value.GetType() == typeof(double))

 29                     return angleControl.angle;

 30             }

 31             return value;

 32         }

 33 

 34         //下面两个函数是为了在PropertyGrid中显示一个辅助的效果

 35         //可以不用重写

 36         public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)

 37         {

 38             int normalX = (e.Bounds.Width / 2);

 39             int normalY = (e.Bounds.Height / 2);

 40 

 41             e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);

 42             e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);

 43             e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);

 44 

 45             double radians = ((double)e.Value * Math.PI) / (double)180;

 46             e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,

 47                 e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),

 48                 e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));

 49         }

 50 

 51         public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)

 52         {

 53             return true;

 54         }

 55     }

 56 

 57     // 这里是我们要显示出来的编辑器,把它作为一个内置类

 58     //从UserControl继承,要在上面EditValue函数中使用的

 59     internal class AngleControl2 : System.Windows.Forms.Form

 60     {

 61         public double angle; //编辑的角度

 62         private float x;     //鼠标位置

 63         private float y;

 64 

 65         public AngleControl(double initial_angle)

 66         {

 67             this.angle = initial_angle;

 68         }

 69         //显现时,显示属性的当前值

 70         protected override void OnLoad(EventArgs e)

 71         {

 72             int originX = (this.Width / 2);

 73             int originY = (this.Height / 2);

 74             this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);

 75             this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);

 76             base.OnLoad(e);

 77         }

 78 

 79         //绘制控件,用来显示编辑角度

 80         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

 81         {

 82             int originX = (this.Width / 2);

 83             int originY = (this.Height / 2);

 84 

 85             e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);

 86             e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);

 87 

 88             e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);

 89         }

 90         //鼠标移动时设置角度

 91         protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)

 92         {

 93             if (e.Button == MouseButtons.Left)

 94             {

 95                 int originX = (this.Width / 2);

 96                 int originY = (this.Height / 2);

 97                 double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));

 98                 double h = e.Y - originY;

 99                 this.angle = Math.Asin(h / len);

100                 if ((e.X >= originX && e.Y >= originY))

101                 {

102                     this.x = (float)(50 * Math.Cos(this.angle) + originX);

103                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

104                     this.angle = this.angle * 180 / Math.PI;

105                 }

106                 else if (e.X < originX && e.Y > originY)

107                 {

108                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

109                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

110                     this.angle = 180 - this.angle * 180 / Math.PI;

111                 }

112                 else if (e.X < originX && e.Y < originY)

113                 {

114                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

115                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

116                     this.angle = 180 - this.angle * 180 / Math.PI;

117                 }

118                 else if (e.X >= originX && e.Y <= originY)

119                 {

120                     this.x = (float)(originX + 50 * Math.Cos(this.angle));

121                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

122                     this.angle = 360 + this.angle * 180 / Math.PI;

123                 }

124                 this.Invalidate();

125             }

126           

127         }

128       

129 }
View Code

  可以看到,只修改了三个地方:

  1. AngleEditor类中GetEditStyle函数返回Modal,表明是以弹出式编辑。
  2. AngleEditor类中EditValue函数中调用编辑控件的方式:

    AngleControl2 angleControl = new AngleControl2((double)value);

    edSvc.ShowDialog(angleControl);

  3.AngleControl2从Form继承,让他显示为对话框,这里为了区别上面的AngleControl类,将其改成了AngleControl2。

  现在看看效果:

  PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框

  实现了弹出式的编辑方式。

四.完整代码

  下面是完整的代码:

  
  1 using System;

  2 using System.ComponentModel;

  3 using System.Drawing;

  4 using System.Drawing.Design;

  5 using System.Windows.Forms;

  6 using System.Windows.Forms.Design;

  7 

  8 namespace TestUITypeEditor

  9 {

 10     //编辑器类

 11  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]

 12     public class AngleEditor : System.Drawing.Design.UITypeEditor

 13     {

 14         public AngleEditor()

 15         {

 16         }

 17 

 18         //下拉式还是弹出式

 19         public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)

 20         {

 21             return UITypeEditorEditStyle.DropDown;

 22             //return UITypeEditorEditStyle.Modal;

 23         }

 24 

 25         //编辑属性值

 26         public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)

 27         {

 28             if (value.GetType() != typeof(double))

 29                 return value;

 30 

 31             //显示编辑框

 32             IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

 33             if (edSvc != null)

 34             {

 35                 AngleControl angleControl = new AngleControl((double)value);

 36                 edSvc.DropDownControl(angleControl);

 37                 //AngleControl2 angleControl = new AngleControl2((double)value);

 38                 //edSvc.ShowDialog(angleControl);

 39 

 40                 // 获取返回值

 41                 if (value.GetType() == typeof(double))

 42                     return angleControl.angle;

 43             }

 44             return value;

 45         }

 46 

 47         //绘制辅助属性显示

 48         public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)

 49         {

 50             int normalX = (e.Bounds.Width / 2);

 51             int normalY = (e.Bounds.Height / 2);

 52 

 53             e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);

 54             e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);

 55             e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);

 56 

 57             double radians = ((double)e.Value * Math.PI) / (double)180;

 58             e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,

 59                 e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),

 60                 e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));

 61         }

 62 

 63         //使用辅助属性显示

 64         public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)

 65         {

 66             return true;

 67         }

 68     }

 69 

 70     // 下拉式编辑方式

 71     internal class AngleControl : System.Windows.Forms.UserControl

 72     {

 73         public double angle;

 74         private float x;

 75         private float y;

 76 

 77         public AngleControl(double initial_angle)

 78         {

 79             this.angle = initial_angle;

 80         }

 81 

 82         protected override void OnLoad(EventArgs e)

 83         {

 84             int originX = (this.Width / 2);

 85             int originY = (this.Height / 2);

 86 

 87             this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);

 88             this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);

 89 

 90             base.OnLoad(e);

 91         }

 92 

 93         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

 94         {

 95             int originX = (this.Width / 2);

 96             int originY = (this.Height / 2);

 97 

 98             e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);

 99             e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);

100 

101             e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);

102         }

103 

104         protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)

105         {   

106             if (e.Button == MouseButtons.Left)

107             {

108                 int originX = (this.Width / 2);

109                 int originY = (this.Height / 2);

110                 double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));

111                 double h = e.Y - originY;

112                 this.angle = Math.Asin(h / len);

113                 if ((e.X >= originX && e.Y >= originY))

114                 {

115                     this.x = (float)(50 * Math.Cos(this.angle) + originX);

116                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

117 

118                     this.angle = this.angle * 180 / Math.PI;

119                 }

120                 else if (e.X < originX && e.Y > originY)

121                 {

122                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

123                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

124 

125                     this.angle = 180 - this.angle * 180 / Math.PI;

126                 }

127                 else if (e.X < originX && e.Y < originY)

128                 {

129                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

130                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

131 

132                     this.angle = 180 - this.angle * 180 / Math.PI;

133                 }

134                 else if (e.X >= originX && e.Y <= originY)

135                 {

136                     this.x = (float)(originX + 50 * Math.Cos(this.angle));

137                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

138 

139                     this.angle = 360 + this.angle * 180 / Math.PI;

140                 }

141 

142                 this.Invalidate();

143             }

144         } 

145     }

146 

147 

148     //弹出式编辑框

149     internal class AngleControl2 : System.Windows.Forms.Form

150     {

151         public double angle;

152         private float x;

153         private float y;

154 

155         public AngleControl2(double initial_angle)

156         {

157             this.angle = initial_angle;

158         }

159 

160         protected override void OnLoad(EventArgs e)

161         {

162             int originX = (this.Width / 2);

163             int originY = (this.Height / 2);

164 

165             this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);

166             this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);

167 

168             base.OnLoad(e);

169         }

170 

171         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

172         {

173             int originX = (this.Width / 2);

174             int originY = (this.Height / 2);

175 

176             e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);

177             e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);

178 

179             e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);

180         }

181 

182         protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)

183         {

184             if (e.Button == MouseButtons.Left)

185             {

186                 int originX = (this.Width / 2);

187                 int originY = (this.Height / 2);

188                 double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));

189                 double h = e.Y - originY;

190                 this.angle = Math.Asin(h / len);

191                 if ((e.X >= originX && e.Y >= originY))

192                 {

193                     this.x = (float)(50 * Math.Cos(this.angle) + originX);

194                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

195 

196                     this.angle = this.angle * 180 / Math.PI;

197                 }

198                 else if (e.X < originX && e.Y > originY)

199                 {

200                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

201                     this.y = (float)(50 * Math.Sin(this.angle) + originY);

202 

203                     this.angle = 180 - this.angle * 180 / Math.PI;

204                 }

205                 else if (e.X < originX && e.Y < originY)

206                 {

207                     this.x = (float)(originX - 50 * Math.Cos(this.angle));

208                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

209 

210                     this.angle = 180 - this.angle * 180 / Math.PI;

211                 }

212                 else if (e.X >= originX && e.Y <= originY)

213                 {

214                     this.x = (float)(originX + 50 * Math.Cos(this.angle));

215                     this.y = (float)(originY + 50 * Math.Sin(this.angle));

216 

217                     this.angle = 360 + this.angle * 180 / Math.PI;

218                 }

219 

220                 this.Invalidate();

221             }

222         }

223     }

224 

225 

226     //控件

227     public class MyControl : System.Windows.Forms.UserControl

228     {

229         private double _angle;

230 

231         [BrowsableAttribute(true)]

232         [EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))]

233         public double Angle

234         {

235             get

236             { return _angle; }

237             set

238             { _angle = value; }

239         }

240 

241 

242         public MyControl()

243         {

244             this._angle = 90;

245         }

246 

247         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

248         {

249             e.Graphics.DrawString("The Angle is " + _angle, this.Font, Brushes.Red,0,0);

250         }

251     }

252 }
View Code

  新建Window工程,添加该文件,在工具箱中将MyControl控件拖入Form,在属性框中编辑Angle属性。

  这里我们把AngleControl和AngleControl2都集成在里面了,当然实际只需选中一种,要实现弹出式,只需按照(三)中的方法,修改AngleEditor中两个地方即可。

 

你可能感兴趣的:(property)