自定义类型复合属性的表示
类似point等.net中已定义的复杂类型,propertyGrid提供了很好的表示方法。例如,A类含有一point型的属性,其在propertyGrid中其值就会表示为(x,y)型,通过展开该属性,还支持分别修改X和Y。但是用户自定义的复杂类默认值显示为该类的toString(),也就是类名。为了实现复杂属性的表示及更好的UI支持我们需要使用TypeConverter类。代码如下:
class Class2 //自定义复杂类包含int型属性两个
{
private int b;
private int a;
public Class2()
{
a = 1;
b = 2;
v = false;
}
public int B
{
get { return b; }
set { b = value; }
}
public int A
{
get { return a; }
set { a = value; }
}
}
class Class1//拥有以自定义类型对象为属性的类
{
private Class2 ins2;
public Class1()
{
ins2 = new TClass2(c);
}
[TypeConverter(typeof(Class2TypeConverter)), Browsable(true)]//使用typeConverter
public TClass2 INS2
{
get { return ins2; }
set { ins2 = value; }
}
}
class Class2TypeConverter:ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)//是否可以从sourceType转换为自定义类
{
if (sourceType == typeof(String)) return true;
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)//是否可以装换为destinationType
{
if (destinationType == typeof(TClass2)) return true;
else if (destinationType == typeof(InstanceDescriptor))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{//用户实现从许可类型(which canconvertfrom() returns true)的value向自定义类型的转换
if (value is string)
{
string[] value1 = value.ToString().Split(',');
TClass2 cls = new TClass2();
cls.A = Convert.ToInt32(value1[0]);
cls.B = Convert.ToInt32(value1[1]);
return cls;
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{//用户实现将自定义类型向许可类型(which canconverterto returns true)的转换,和上一方法互为逆向过程
if(destinationType == typeof(String))
{
TClass2 temp = (TClass2)value;
string result;
result = temp.A.ToString() + ",";
result += temp.B.ToString();
return result;
}
else if (destinationType == typeof(InstanceDescriptor) && (value is TClass2))
{
TClass2 temp = (TClass2)value;
string[] sto = new string[2];
sto[0] = temp.A.ToString();
sto[1] = temp.B.ToString();
Type[] types = new Type[2];
types[0] = typeof(int);
types[1] = typeof(int);
String[] str = new string[1];
str[0] = String.Join(",", sto);
return new InstanceDescriptor(typeof(TClass2).GetConstructor(types),str);
}
return base.ConvertTo(context, culture, value, destinationType);
}public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return base.GetPropertiesSupported(context);
}
}