属性网格项和DoubleClick

我正在使用PropertyGrid控件来编辑应用程序中的某些对象。 我正在使用自定义TypeConverters和TypeEditors来获得更好的用户界面。

我对自定义TypeConverter的布尔属性有问题。 如果我有这个课程:

public class MyClass { public string Name { get; set; } [System.ComponentModel.TypeConverter( typeof( BoolTypeConverter ) )] public bool Flag { get; set; } } 

然后我在PropertyGrid中创建实例并将其设置为SelectedObject – 一切正常,直到用户在属性网格项上格式化“Flag”属性。 在DoubleClick发出此消息后: alt text http://tcks.wz.cz/property_grid_error.PNG

TypeConverter类看起来:

 public class BoolTypeConverter : System.ComponentModel.TypeConverter { public const string TEXT_TRUE = "On"; public const string TEXT_FALSE = "Off"; public const string TEXT_NONE = ""; public override object CreateInstance( System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary propertyValues ) { object ret = base.CreateInstance( context, propertyValues ); return ret; } public override bool GetCreateInstanceSupported( System.ComponentModel.ITypeDescriptorContext context ) { bool ret = base.GetCreateInstanceSupported( context ); return ret; } public override bool IsValid( System.ComponentModel.ITypeDescriptorContext context, object value ) { bool ret; if ( value is string ) { string tmpValue = value.ToString().Trim(); if ( string.Compare( tmpValue, TEXT_NONE, StringComparison.InvariantCultureIgnoreCase ) == 0 ) { ret = true; } else if ( string.Compare( tmpValue, TEXT_TRUE, StringComparison.InvariantCultureIgnoreCase ) == 0 ) { ret = true; } else if ( string.Compare( tmpValue, TEXT_FALSE, StringComparison.InvariantCultureIgnoreCase ) == 0 ) { ret = true; } else { bool blValue; ret = bool.TryParse( tmpValue, out blValue ); } } else { ret = base.IsValid( context, value ); } return ret; } public override bool CanConvertFrom( System.ComponentModel.ITypeDescriptorContext context, Type sourceType ) { bool ret = false; if ( sourceType == typeof( string ) ) { ret = true; } else { ret = base.CanConvertFrom( context, sourceType ); } return ret; } public override object ConvertFrom( System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value ) { object ret = null; bool converted = false; if ( value is string ) { string tmpValue = value.ToString().Trim(); if ( string.Compare( tmpValue, TEXT_NONE, StringComparison.InvariantCultureIgnoreCase ) == 0 || string.IsNullOrEmpty( tmpValue ) ) { ret = null; converted = true; } else if ( string.Compare( tmpValue, TEXT_TRUE, StringComparison.InvariantCultureIgnoreCase ) == 0 ) { ret = true; converted = true; } else if ( string.Compare( tmpValue, TEXT_FALSE, StringComparison.InvariantCultureIgnoreCase ) == 0 ) { ret = false; converted = true; } else { bool blValue; if ( converted = bool.TryParse( tmpValue, out blValue ) ) { ret = blValue; } } } if ( false == converted ) { ret = base.ConvertFrom( context, culture, value ); } return ret; } public override bool CanConvertTo( System.ComponentModel.ITypeDescriptorContext context, Type destinationType ) { bool ret = false; if ( destinationType == typeof( bool ) ) { ret = true; } else { ret = base.CanConvertTo( context, destinationType ); } return ret; } public override object ConvertTo( System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType ) { object ret = null; bool converted = false; if ( destinationType == typeof( string ) ) { if ( null == value ) { ret = TEXT_NONE; converted = true; } else if ( value is bool? || value is bool ) { if ( (bool)value ) { ret = TEXT_TRUE; } else { ret = TEXT_FALSE; } converted = true; } else if ( value is string ) { ret = value; converted = true; } } if ( false == converted ) { ret = base.ConvertTo( context, culture, value, destinationType ); } return ret; } public override StandardValuesCollection GetStandardValues( System.ComponentModel.ITypeDescriptorContext context ) { StandardValuesCollection ret; Type tpProperty = context.PropertyDescriptor.PropertyType; if ( tpProperty == typeof( bool ) ) { ret = new StandardValuesCollection( new string[]{ TEXT_TRUE, TEXT_FALSE } ); } else if ( tpProperty == typeof( bool? ) ) { ret = new StandardValuesCollection( new string[]{ TEXT_TRUE, TEXT_FALSE, TEXT_NONE } ); } else { ret = new StandardValuesCollection( new string[0] ); } return ret; } public override bool GetStandardValuesSupported( System.ComponentModel.ITypeDescriptorContext context ) { bool ret; Type tpProperty = context.PropertyDescriptor.PropertyType; if ( tpProperty == typeof( bool ) || tpProperty == typeof( bool? ) ) { ret = true; } else { ret = false; } return ret; } } 

这种行为对用户来说非常混乱。 我该怎样预防呢?

谢谢

你的GetStandardValues()方法是错误的。 它必须返回属性类型,而不是字符串:

 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { StandardValuesCollection ret; Type tpProperty = context.PropertyDescriptor.PropertyType; if (tpProperty == typeof(bool)) ret = new StandardValuesCollection(new object[] { true, false }); else if (tpProperty == typeof(bool?)) ret = new StandardValuesCollection(new object[] { true, false, null }); else ret = new StandardValuesCollection(new object[0]); return ret; }