自定义控件开发6---TypeConvert(类似编辑坐标)

 public class MyTypeConvert :ExpandableObjectConverter
    {
        
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            
return (sourceType == typeof(string|| base.CanConvertFrom(context, sourceType));
        }
        
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            
return (destinationType == typeof(string|| base.CanConvertFrom(context, destinationType));
        }
        
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
            
object value)
        {
            
string str = value as string;
            
if (str == null)
            {
                
return base.ConvertFrom(context, culture, value);
            }
            
string str2 = str.Trim();
            
if (str2.Length == 0return null;
            
if (culture == null) culture = CultureInfo.CurrentCulture;
            
char ch = culture.TextInfo.ListSeparator[0];
            
string[] strArray = str2.Split(new char[] { ch });
            
int[] numArray = new int[strArray.Length];
            TypeConverter converter 
= TypeDescriptor.GetConverter(typeof(int));
            
for (int i = 0; i < numArray.Length; i++)
            {
                numArray[i] 
= (int)converter.ConvertFromString(context, culture, strArray[i]);
            }
            
if (numArray.Length != 3)
            {
                
throw new Exception("格式不正确!");
            }
            
return new SolidCoordinate(numArray[0], numArray[1], numArray[2]);
        }
        
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            
if (destinationType == null)
            {
                
throw new Exception("目标类型不能为空!");
            }
            
if (value is SolidCoordinate)
            {
                
if (destinationType == typeof(string))
                {
                    SolidCoordinate solidCoordinate 
= (SolidCoordinate)value;
                    
if (culture == null)
                    {
                        culture 
= CultureInfo.CurrentCulture;
                    } 
string separator = culture.TextInfo.ListSeparator + " ";
                    TypeConverter converter 
= TypeDescriptor.GetConverter(typeof(int));
                    
string[] strArray = new string[3];
                    
int num = 0;
                    strArray[num
++= converter.ConvertToString(context, culture,
                    solidCoordinate.X);
                    strArray[num
++= converter.ConvertToString(context, culture,
                    solidCoordinate.Y);
                    strArray[num
++= converter.ConvertToString(context, culture,
                    solidCoordinate.Z);
                    
return string.Join(separator, strArray);
                } 
                
if (destinationType == typeof(InstanceDescriptor))
                {
                    SolidCoordinate solidCoordinate2 
= (SolidCoordinate)value;
                    ConstructorInfo constructor 
= typeof(SolidCoordinate).
                    GetConstructor(
new Type[] { typeof(int), typeof(int), typeof(int) });
                    
if (constructor != null)
                    {
                        
return new InstanceDescriptor(constructor, new object[] { solidCoordinate2.X, solidCoordinate2.Y, solidCoordinate2.Z });
                    }
                }
            } 
            
return base.ConvertTo(context, culture, value, destinationType);
        }
        
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
        {
            
if (propertyValues == null)
            {
                
throw new Exception("属性值不能为空!");
            } 
            
object obj2 = propertyValues["X"];
            
object obj3 = propertyValues["Y"];
            
object obj4 = propertyValues["Z"];
            
if (((obj2 == null|| (obj3 == null|| (obj4 == null)) || (!(obj2 is int|| !(obj3 is int|| !(obj4 is int)))
            {
                
throw new Exception("格式不正确!");
            }
            
return new SolidCoordinate((int)obj2, (int)obj3, (int)obj4);
        }
        
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
        {
            
return true;
        }
        
//public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, 
        
//    Attribute[] attributes)
        
//{
        
//    return TypeDescriptor.GetProperties(typeof(SolidCoordinate), attributes).Sort(new string[] { "X", "Y", "Z" });
        
//}
    }

从上面的代码中,我们看到override ConvertTo()方法时,当没有判断DestinationType 是否是InstanceDescriptor时, 当我们将控件拖入页面编辑属性,

再次编译时就会抛出'Unable to generate code for a value of type 'MyControls.Positions'. This error occurred while trying to generate the property value for MyPositions.'

为什呢?那是因为TypeConvertor必须从string转换成目标类型(ConvertFrom)或转换成string类型(TypeConvertor.ConvertTo).并且同时需要转换成InstanceDescriptior.

 if (destinationType == typeof(InstanceDescriptor))
                {
                    Positions obj2 
= value as Positions;
                    ConstructorInfo constructor 
= typeof(Positions).GetConstructor(
                        
new Type[] { typeof(int), typeof(int), typeof(int) });
                    
if (constructor != null)
                        
return new InstanceDescriptor(constructor,
                            
new object[] { obj2.X, obj2.Y, obj2.Z });
                }

更多详细解释.http://weblogs.asp.net/bleroy/archive/2005/04/28/405013.aspx

DownLoad

posted on 2009-11-26 18:25  博览潇湘  阅读(531)  评论(0)    收藏  举报

导航