自定义控件开发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 == 0) return 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" });
//}
}
{
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 == 0) return 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 });
}
{
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
浙公网安备 33010602011771号