在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; } } SizeF属性类的定义: /**/ /// <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;}}