日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义类在PropertyGrid上的展示方法

發布時間:2024/4/17 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义类在PropertyGrid上的展示方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自定義類在PropertyGrid上的展示方法

零.引言

  PropertyGrid用來顯示某一對象的屬性,但是并不是所有的屬性都能編輯,基本數據類型(int, double等)和.Net一些封裝的類型(Size,Color等)可以編輯,但是對于自己定義的類型屬性,是不能編輯的,本文主要講述如何為自定義類型作為屬性時,在PropertyGrid中進行編輯,以及進行設計時序列化,本文主要參考MSDN,錯誤和不足之處還望指正。

一.自定義類屬性

  在PropertyGrid中能夠編輯的都是.Net中自己封裝的類,如果在一個類中有一個屬性是我們自己定義的類型,在PropertyGrid中會是怎樣的呢?看下面這個例子:

  假如現在有一個類Line:

?Line

?  有一個控件類包含一個Line類型的屬性:

1 public class MyControl : System.Windows.Forms.UserControl2 {3 Line _line;4 5 public MyControl()6 {7 _line = new Line(new Point(0, 0),new Point(100, 100));8 }9 10 public Line MyLine 11 { 12 get{return _line;} 13 set{_line = value;} 14 } 15 16 protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 17 { 18 e.Graphics.DrawLine(Pens.Red, this._line.Point1, this._line.Point2); 19 base.OnPaint(e); 20 } 21 }

  重新生成,從工具箱中將該控件拖入Form中,查看他的屬性,在PropertyGrid中顯示如下:

  

  可見MyLine屬性的值不顯示,且是不能編輯的。這是因為PropertyGrid根本不知道Line是個什么類型,不知道要怎么顯示,如果要其能在PropertyGrid中顯示,必須給他提供轉換器。

二.轉換器概念

  PropertyGrid中屬性的值都是以字符串的形式呈現給我們看的,顯示一個對象的屬性時,要將對象的屬性值轉換為字符串顯示出來,而設置屬性時,要將字符串轉換為對象的屬性值。這就需要一個轉換器。在.Net中定義了一個TypeConverter?類,用來作為這些轉換器的基類。.Net為一些類設計了專門的轉換類,如:System.Drawing.ColorConverter ,System.Drawing.FontConverter等等,(具體參見MSDN中TypeConverter的繼承關系)因此在PropertyGrid中能直接編輯這些屬性。我們自己定義的類沒有這樣的類型轉換器,因此在PropertyGrid中無法編輯,需要設計自己的轉換器。

  先來看一下MSDN中對TypeConverter的描述:TypeConverter類提供一種將值的類型轉換為其他類型以及訪問標準值和子屬性的統一方法。

  繼承者說明:

  從 TypeConverter 繼承,以實現您自己的轉換要求。當從類繼承時,可以重寫以下方法:

  • 若要支持自定義類型轉換,請重寫?CanConvertFrom、CanConvertTo、ConvertFrom?和?ConvertTo?方法。
  • 若要轉換必須重新創建對象才能更改其值的類型,請重寫?CreateInstance?和?GetCreateInstanceSupported?方法。
  • 若要轉換支持屬性 (Property) 的類型,請重寫?GetProperties?和?GetPropertiesSupported?方法。如果轉換的類沒有屬性 (Property),而您需要實現屬性 (Property),則可以將?TypeConverter.SimplePropertyDescriptor?類用作實現屬性 (Property) 說明符的基。當從?TypeConverter.SimplePropertyDescriptor?繼承時,必須重寫 GetValue 和 SetValue 方法。
  • 若要轉換支持標準值的類型,請重寫?GetStandardValues、GetStandardValuesExclusive、GetStandardValuesSupported?和?IsValid?方法。

三.添加轉換器

  好了,了解了基本原理后,我們來為Line添加轉換器。這里新建一個LineConverter類,并繼承于TypeConverter。

?LineConverter

  在轉換器類中,我們重寫了四個函數,也就是在繼承者說明中第一條的四個函數:

  ①?CanConvertTo:用來說明此類可以轉換為哪些類型,能轉換就返回true,這里我們讓他能轉換為string和InstanceDescriptor,InstanceDescriptor是存儲描述對象實例的信息,這些信息可用于創建對象的實例。一般轉換都要實現這個轉換,后面進行說明。

  ②?CanConvertFrom:說明該類能有什么類型轉換過來,能轉換返回true,這里只對string類型進行轉換。

  ③?ConvertTo:具體的轉換實現,也就是提供方法將該類轉換為在CanConvertTo中確定可以轉換的類型。這里實現string和InstanceDescriptor的轉換。

  ④?ConvertFrom:具體的轉換實現,也就是提供方法將該類轉換為在CanConvertFrom中確定可以轉換的類型。這里實現string的轉換。

  注意,每個方法處理完自己的轉換后,依然要調用基類的函數來處理其他的情況。

  重寫這四個方法后,給Line類型加上TypeConverter特性,在Line類定義的上面加上[TypeConverter(typeof(LineConverter))]。這樣在需要轉換的地方,就會調用我們所寫的方法進行轉換,Line屬性在PropertyGrid中顯示時,會調用ConvertTo,轉換為字符串輸出;設置屬性時,會調用ConvertFrom將字符串轉換為屬性值,當然,字符串必須要有一定的格式,這就需要在轉換的過程中進行判斷,見ConvertFrom方法。

  重新生成,現在看MyControl中MyLine屬性在PropertyGrid中的顯示:

  

  可以看到MyLine屬性顯示出來了(以x1,y1,x2,y2的格式,我們在ConverTo方法中指定的),并可以編輯了,但必須是x1,y1,x2,y2的格式,否則會出現如下錯誤提示:

  

  這是我們在ConvertFrom方法中進行判斷的。

四.編輯復雜屬性的子屬性

  現在可以編輯屬性了,但是必須使用x1,y1,x2,y2固定的格式,不方便,而且容易出錯,可不可以分別設置Line的兩個點呢,可以,這里就需要編輯子屬性了。Line中有Point1和Point2兩個屬性,我們讓他們也顯示出來。

  這里就是繼承者說明中的第三條了。重寫?GetProperties?和?GetPropertiesSupported?方法。在LineConverter中重寫這兩個方法:

1 public override bool GetPropertiesSupported(ITypeDescriptorContext context)2 {3 return true;4 //return base.GetPropertiesSupported(context);5 }6 7 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)8 {9 return TypeDescriptor.GetProperties(value, attributes); 10 //return base.GetProperties(context, value, attributes); 11 } 12

  重新生成,現在看MyControl中MyLine屬性在PropertyGrid中的顯示:

  

  可以看到現在我們可以編輯MyLine的子屬性了。

五.屬性的設計時串行化

  最后說一說ConvertTo方法中為什么要實現InstanceDescriptor的轉換。Visual Studio在我們編輯控件時,會在Form1.Designer.cs文件中自動的生成代碼,設置控件的屬性,這叫屬性對設計時序列化,如下:

  

  我們定義的MyLine屬性,在這里并沒有,如何使它出現在這里呢,只需給MyLine屬性加上DesignerSerializationVisibility特性。如下

1 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 2 public Line MyLine3 {4 get5 {6 return _line;7 }8 set9 { 10 _line = value; 11 } 12 } 13

  這里DesignerSerializationVisibility.Visible表明代碼生成器生成對象的代碼。DesignerSerializationVisibility.Content說明該屬性在編輯時要代碼生成器產生對象內容的代碼,而不是對象本身的代碼。DesignerSerializationVisibility.Hide代碼生成器不生成對象的代碼。

  重新生成,并改變控件的位置,打開Form1.Designer.cs,會發現自動生成了MyLine屬性的設置值。

  

  這是如何生成的呢,關鍵就在ConvertTo方法中實現InstanceDescriptor的轉換,該方法告訴代碼生成器,如何去構造一個Line類型,生成時,調用Line的構造函數構造新對象初始化MyLine屬性值。

六.總體的代碼

  下面是完整的代碼:

1 using System;2 using System.ComponentModel;3 using System.ComponentModel.Design.Serialization;4 using System.Drawing;5 using System.Globalization;6 using System.Reflection;7 8 namespace TestTypeConverter9 {10 //線條類11 [TypeConverter(typeof(LineConverter))]12 public class Line13 {14 // Line members.15 Point P1;16 Point P2;17 18 public Point Point119 {20 get21 {22 return P1;23 }24 set25 {26 P1 = value;27 }28 }29 30 public Point Point231 {32 get33 {34 return P2;35 }36 set37 {38 P2 = value;39 }40 }41 42 public Line(Point point1, Point point2)43 {44 P1 = point1;45 P2 = point2;46 }47 }48 49 //轉換器類50 public class LineConverter : TypeConverter51 {52 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)53 {54 if (destinationType == typeof(string))55 {56 return true;57 }58 59 if (destinationType == typeof(InstanceDescriptor))60 {61 return true;62 }63 return base.CanConvertTo(context, destinationType);64 }65 66 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)67 {68 if (sourceType == typeof(string))69 {70 return true;71 }72 73 return base.CanConvertFrom(context, sourceType);74 }75 76 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)77 {78 if (destinationType == typeof(string) && value != null)79 {80 Line t = (Line)value;81 string str = t.Point1.X + "," + t.Point1.Y + "," + t.Point2.X + "," + t.Point2.Y;82 return str;83 }84 85 if (destinationType == typeof(InstanceDescriptor))86 {87 ConstructorInfo ci = typeof(TestTypeConverter.Line).GetConstructor(new Type[] { typeof(Point), typeof(Point) });88 Line t = (Line)value;89 return new InstanceDescriptor(ci, new object[] { t.Point1, t.Point2 });90 }91 return base.ConvertTo(context, culture, value, destinationType);92 }93 94 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)95 {96 if (value is string)97 {98 string str = (string)value;99 str = str.Trim(); 100 string[] v = str.Split(','); 101 if (v.Length != 4) 102 { 103 throw new NotSupportedException("Invalid parameter format"); 104 } 105 106 int x1 = 0; 107 int y1 = 0; 108 int x2 = 0; 109 int y2 = 0; 110 bool res = int.TryParse(v[0], out x1); 111 if (res == false) throw new NotSupportedException("Invalid parameter format"); 112 res = int.TryParse(v[1], out y1); 113 if (res == false) throw new NotSupportedException("Invalid parameter format"); 114 res = int.TryParse(v[2], out x2); 115 if (res == false) throw new NotSupportedException("Invalid parameter format"); 116 res = int.TryParse(v[3], out y2); 117 if (res == false) throw new NotSupportedException("Invalid parameter format"); 118 119 Line line = new Line(new Point(x1, y1), new Point(x2, y2)); 120 return line; 121 } 122 123 return base.ConvertFrom(context, culture, value); 124 } 125 126 127 public override bool GetPropertiesSupported(ITypeDescriptorContext context) 128 { 129 return true; 130 //return base.GetPropertiesSupported(context); 131 } 132 133 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 134 { 135 return TypeDescriptor.GetProperties(value, attributes); 136 //return base.GetProperties(context, value, attributes); 137 } 138 } 139 140 //控件類 141 public class MyControl : System.Windows.Forms.UserControl 142 { 143 Line _line; 144 145 public MyControl() 146 { 147 _line = new TestTypeConverter.Line( 148 new Point(0, 0), 149 new Point(100, 100) 150 ); 151 } 152 153 [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 154 public Line MyLine 155 { 156 get 157 { 158 return _line; 159 } 160 set 161 { 162 _line = value; 163 } 164 } 165 166 protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 167 { 168 e.Graphics.DrawLine(Pens.Red, this._line.Point1, this._line.Point2); 169 base.OnPaint(e); 170 } 171 } 172 }

  新建一個Windows工程,添加該文件,在工具箱中找到我們的MyControl控件,拖入Form中,在屬性框中查看控件的屬性。

?

轉載于:https://www.cnblogs.com/pdf2pdf/p/8232069.html

總結

以上是生活随笔為你收集整理的自定义类在PropertyGrid上的展示方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩人体视频 | 免费成人福利视频 | mm131美女视频 | 国产伦精品一区三区精东 | 欧美激情18 | 国产乱仑视频 | 97激情 | 噜啪啪| 少妇高潮视频 | 4438x亚洲最大 | 久热免费视频 | 狠狠撸在线观看 | 日韩av综合在线 | 99欧美精品 | 亚洲精品福利网站 | 无码人妻精品一区二区三区夜夜嗨 | 成人性爱视频在线观看 | 日韩欧美中文字幕在线播放 | 人妻精品一区二区在线 | 视频一区在线观看 | 色呦呦官网 | 精品一区二区在线视频 | 欧美综合视频在线观看 | 麻豆午夜 | 国产一区二区三区高清 | 夜夜精品一区二区无码 | 久久尹人 | 亚洲最大的黄色网 | www.国产精品视频 | 四虎成人精品在永久免费 | 亚洲男女视频 | 西西毛片 | 国产免费高清视频 | 被两个男人吃奶三p爽文 | 国产91国语对白在线 | 色视av | 色噜噜狠狠狠综合曰曰曰88av | 在线中文字幕视频 | 国产成人久久婷婷精品流白浆 | 精品国产av一区二区 | 麻豆传媒在线 | 欧美资源站 | 手机在线观看av网站 | 欧美高清视频一区 | 激情三级在线 | 国产91精品欧美 | 欧美一区二区三区激情啪啪 | 中文字幕在线观看线人 | 国产青草视频在线观看 | 欧美春色| 成年人免费观看视频网站 | 中文字幕无码乱码人妻日韩精品 | 久青草资源福利视频 | 日韩一区二区三区高清 | 福利视频导航网 | 五月天导航 | 亚洲午夜免费 | 国产自产一区二区 | 激情综合久久 | 西西4444www大胆无码 | 高h免费视频 | 韩国成人在线视频 | 少妇一级淫片免费放 | 欧美日韩激情视频在线观看 | 久久在线| 91国内精品视频 | 久久国产精品久久精品国产 | 亚洲成人播放器 | 色综合国产 | 色呦呦精品| 久久另类ts人妖一区二区 | 女人做爰全过程免费观看美女 | 中文字幕在线第一页 | 玖玖爱在线观看 | 九热视频在线观看 | 国产又粗又猛又爽免费视频 | 色天天综合网 | 青青成人在线 | 日韩一区二区在线免费观看 | 视色av | 日韩一区二区在线观看 | 国产原创视频在线 | 久久久成| 免费久久一级欧美特大黄 | 国产日本一区二区三区 | 免费99精品国产自在在线 | 亚洲欧洲日本国产 | 超碰成人在线观看 | 亚洲精品香蕉 | 国产真实老熟女无套内射 | 欧美春色 | 国产成人亚洲精品自产在线 | 国产成人福利 | 丰满人妻一区二区三区性色 | a级一片 | 伊人色综合网 | 欧美午夜精品久久久久久孕妇 | 国产99在线 | 少妇高潮一区二区三区69 |