zoukankan      html  css  js  c++  java
  • 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属性了,效果如下:

      

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

    三.弹出式编辑方式

      实现了下拉式,我们来实现弹出式,弹出式和下拉式非常的相像,现在要弹出一个编辑框,因此我们的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。

      现在看看效果:

      

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

    四.完整代码

      下面是完整的代码:

      
      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中两个地方即可。

  • 相关阅读:
    ###JS获取URL参数的函数###
    Ant通配符
    java.lang.OutOfMemoryError处理错误
    超越最常用的快捷键
    一个完整的工作流管理系统成部分
    Caused by: org.hibernate.hql.ast.QuerySyntaxException: TkltEmpQuitProcess is not mapped. (SSH项目中出现的映射问题)
    小的心得
    diary record 20120423
    小的思想
    用3种方法检测远程URL是否存在。
  • 原文地址:https://www.cnblogs.com/yongyu/p/4230331.html
Copyright © 2011-2022 走看看