零.引言
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 }
其中有个属性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 }
这里有两个类,一个是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 }
好了,现在就可以使用下拉框来编辑我们的Angle属性了,效果如下:
上面那个圆圈就是我们用来编辑角度的。
三.弹出式编辑方式
实现了下拉式,我们来实现弹出式,弹出式和下拉式非常的相像,现在要弹出一个编辑框,因此我们的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 }
可以看到,只修改了三个地方:
- AngleEditor类中GetEditStyle函数返回Modal,表明是以弹出式编辑。
- AngleEditor类中EditValue函数中调用编辑控件的方式:
AngleControl2 angleControl = new AngleControl2((double)value);
edSvc.ShowDialog(angleControl);
3.AngleControl2从Form继承,让他显示为对话框,这里为了区别上面的AngleControl类,将其改成了AngleControl2。
现在看看效果:
实现了弹出式的编辑方式。
四.完整代码
下面是完整的代码:
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 }
新建Window工程,添加该文件,在工具箱中将MyControl控件拖入Form,在属性框中编辑Angle属性。
这里我们把AngleControl和AngleControl2都集成在里面了,当然实际只需选中一种,要实现弹出式,只需按照(三)中的方法,修改AngleEditor中两个地方即可。