龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > asp.net编程 >

如何定制.NET类型转换器简介

时间:2009-12-21 11:47来源:未知 作者:admin 点击:
分享到:
当在设计平面上选中某个组件,你选中的就是这个组件的某个实例,显示在属性浏览器里的书形象都是来自这个实例。当在属性浏览器中对属性进行编辑时,新属性值也将被刷新到这个

当在设计平面上选中某个组件,你选中的就是这个组件的某个实例,显示在属性浏览器里的书形象都是来自这个实例。当在属性浏览器中对属性进行编辑时,新属性值也将被刷新到这个实例中。这很容易理解,但也往往不那么直观,因为属性浏览器只能把属性(不管是什么类型)显示为文本。在属性值在属性浏览器和那个组件实例见来回传递时,他们必须在字符串和他们真实的类型之间来回传递。

既然要进行类型转换,就需要有类型转换器(type converter),他们在.NET中主要用途就是对各种类型进行转换。.NET已经为程序员准备了内建的类型转换器,但如果你的组件或控件包含一些基于定制类型的属性――比如那个时钟控件ClockControl(源代码见《.Net窗体设计阶段的功能集成问答》 )的HourHand,MinuteHand,SecongHand属性,他们就无能为力了:


 1  public class Hand {
 2    private Color  color = Color.Black;
 3    private int    width = 1;
 4    public Hand(Color color, int width) {
 5      this.color = color;
 6      this.width = width;
 7    }

 8
 9    public Color Color {
10      get return color; }
11      set { color = value; }
12    }

13
14    public int Width {
15      get return width; }
16      set { width = value; }
17    }

18  }

 如果没有定制的类型转换器,你只能看到如下图所示画面:

 

创建定制的类型转换器:

1.从TypeConverter基类派生一个新类HandConverter。

2.为了支持类型转换,HandConverter类必须对CanConvertFrom,ConvertTo和ConvertFrom方法进行覆盖。

3.为了让多值属性和嵌套属性具备展开编辑功能,可将基类改为ExpandableObjectConverter。对比效果如下图:

4.对GetCreateInstanceSupportedCreateInstance方法进行覆盖,使得当在属性浏览器里编辑嵌套属性时能立即刷新根属性。(比如你修改HourHand.Color属性,HourHand属性会立刻更新。)


 1  public class HandConverter : ExpandableObjectConverter {
 2    // Don't need to override CanConvertTo if converting to string, as that's what base TypeConverter does
 3    // Do need to override CanConvertFrom since it's base converts from InstanceDescriptor
 4
 5    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
 6      // We can be converted to an InstanceDescriptor
 7      if( destinationType == typeof(InstanceDescriptor) ) return true;
 8      return base.CanConvertTo(context, destinationType);
 9    }

10        
11    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
12      // We can convert from a string to a Hand type
13      if( sourceType == typeof(string) ) return true; }
14      return base.CanConvertFrom(context, sourceType);
15    }

16
17    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo info, object value) {
18
19      // If converting from a string
20      if( value is string ) {
21        // Build a Hand type   
22        try {
23          // Get Hand properties
24          string     propertyList = (string)value;
25          string[]   properties = propertyList.Split(';');
26          return new Hand(Color.FromName(properties[0].Trim()), 
27                          Convert.ToInt32(properties[1]));
28        }

29        catch {}
30        throw new ArgumentException("The arguments were not valid.");
31      }

32      return base.ConvertFrom(context, info, value);
33    }

34        
35    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
36
37      // If source value is a Hand type
38      if( value is Hand ) {
39        // Convert to string
40        if( (destinationType == typeof(string)) ) {
41          Hand     hand = (Hand)value;
42          string   color = (hand.Color.IsNamedColor ? 
43                            hand.Color.Name : 
44                            hand.Color.R + "" + hand.Color.G + "" + hand.Color.B);
45          return string.Format("{0}; {1}", color, hand.Width.ToString());
46        }

47        // Convert to InstanceDescriptor
48        if( (destinationType == typeof(InstanceDescriptor)) ) {
49          Hand       hand = (Hand)value;
50          object[]   properties = new object[2];
51          Type[]     types = new Type[2];
52
53          // Color
54          types[0= typeof(Color);
55          properties[0= hand.Color;
56
57          // Width
58          types[1= typeof(int);
59          properties[1= hand.Width;
60
61          // Build constructor
62          ConstructorInfo   ci = typeof(Hand).GetConstructor(types);
63          return new InstanceDescriptor(ci, properties);
64        }

65      }
                
66      // Base ConvertTo if neither string or InstanceDescriptor required
67  
精彩图集

赞助商链接