在PropertyGrid中,PointF和SizeF类型的属性是只读的,我分析了DotNet中的Point的定义,编写了2个属性类,以此实现在PropertyGrid中可以象Point那样直接修改数据的功能。
PointF属性类的定义:

/**//// <summary>
/// PointFConverter 的摘要说明。
/// </summary>
public class PointFConverter : TypeConverter
...{
// Methods
public PointFConverter()
...{
}
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(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
...{
if (!(value is string))
...{
return base.ConvertFrom(context, culture, value);
}
string text = ((string) value).Trim();
if (text.Length == 0)
...{
return null;
}
if (culture == null)
...{
culture = CultureInfo.CurrentCulture;
}
char ch = culture.TextInfo.ListSeparator[0];
string[] textArray = text.Split(new char[] ...{ ch });
float[] numArray = new float[textArray.Length];
TypeConverter converter = TypeDescriptor.GetConverter(typeof(float));
for (int i = 0; i < numArray.Length; i++)
...{
numArray[i] = (float) converter.ConvertFromString(context, culture, textArray[i]);
}
if (numArray.Length != 2)
...{
throw new ArgumentException("格式不正确!");
}
return new PointF(numArray[0], numArray[1]);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
...{
if (destinationType == null)
...{
throw new ArgumentNullException("destinationType");
}
if ((destinationType == typeof(string)) && (value is PointF))
...{
PointF pointf = (PointF) value;
if (culture == null)
...{
culture = CultureInfo.CurrentCulture;
}
string separator = culture.TextInfo.ListSeparator + " ";
TypeConverter converter = TypeDescriptor.GetConverter(typeof(float));
string[] textArray = new string[2];
int num = 0;
textArray[num++] = converter.ConvertToString(context, culture, pointf.X);
textArray[num++] = converter.ConvertToString(context, culture, pointf.Y );
return string.Join(separator, textArray);
}
if ((destinationType == typeof(InstanceDescriptor)) && (value is SizeF))
...{
PointF pointf2 = (PointF) value;
ConstructorInfo member = typeof(PointF).GetConstructor(new Type[] ...{ typeof(float), typeof(float) });
if (member != null)
...{
return new InstanceDescriptor(member, new object[] ...{ pointf2.X, pointf2.Y });
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
...{
return new PointF((float) propertyValues["X"], (float) propertyValues["Y"]);
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
...{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
...{
return TypeDescriptor.GetProperties(typeof(PointF), attributes).Sort(new string[] ...{ "X", "Y" });
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
...{
return true;
}
}

/**//// <summary>
/// SizeFConverter 的摘要说明。
/// </summary>
public class SizeFConverter : TypeConverter
...{
// Methods
public SizeFConverter()
...{
}
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(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
...{
if (!(value is string))
...{
return base.ConvertFrom(context, culture, value);
}
string text = ((string) value).Trim();
if (text.Length == 0)
...{
return null;
}
if (culture == null)
...{
culture = CultureInfo.CurrentCulture;
}
char ch = culture.TextInfo.ListSeparator[0];
string[] textArray = text.Split(new char[] ...{ ch });
float[] numArray = new float[textArray.Length];
TypeConverter converter = TypeDescriptor.GetConverter(typeof(float));
for (int i = 0; i < numArray.Length; i++)
...{
numArray[i] = (float) converter.ConvertFromString(context, culture, textArray[i]);
}
if (numArray.Length != 2)
...{
throw new ArgumentException("格式不正确!");
}
return new SizeF(numArray[0], numArray[1]);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
...{
if (destinationType == null)
...{
throw new ArgumentNullException("destinationType");
}
if ((destinationType == typeof(string)) && (value is SizeF))
...{
SizeF size = (SizeF) value;
if (culture == null)
...{
culture = CultureInfo.CurrentCulture;
}
string separator = culture.TextInfo.ListSeparator + " ";
TypeConverter converter = TypeDescriptor.GetConverter(typeof(float));
string[] textArray = new string[2];
int num = 0;
textArray[num++] = converter.ConvertToString(context, culture, size.Width);
textArray[num++] = converter.ConvertToString(context, culture, size.Height);
return string.Join(separator, textArray);
}
if ((destinationType == typeof(InstanceDescriptor)) && (value is SizeF))
...{
SizeF size2 = (SizeF) value;
ConstructorInfo member = typeof(SizeF).GetConstructor(new Type[] ...{ typeof(float), typeof(float) });
if (member != null)
...{
return new InstanceDescriptor(member, new object[] ...{ size2.Width, size2.Height });
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
...{
return new SizeF((float) propertyValues["Width"], (float) propertyValues["Height"]);
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
...{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
...{
return TypeDescriptor.GetProperties(typeof(SizeF), attributes).Sort(new string[] ...{ "Width", "Height" });
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
...{
return true;
}
}

使用方法:
[Description("位置信息"),
CategoryAttribute ("1.基础信息"),
TypeConverterAttribute(typeof(PointFConverter))]
public PointF 位置
...{
get...{return base.位置;}
set...{base.位置=value;}
}
[Description("尺寸信息"),
CategoryAttribute ("1.基础信息"),
PropertyOrder(13),
BrowsableAttribute(false),
TypeConverterAttribute(typeof(SizeFConverter))]
public SizeF 尺寸
...{
get...{return base.尺寸;}
set...{base.尺寸=value;}
}
本文介绍如何为.NET中的PointF和SizeF类型创建自定义TypeConverter,使其能在PropertyGrid中实现类似Point类型的直接编辑功能。通过示例代码展示了PointFConverter与SizeFConverter的具体实现方法。
2万+

被折叠的 条评论
为什么被折叠?



