Property Grid Element and DoubleClick

I am using the PropertyGrid control to edit some objects in my application. I use custom TypeConverters and TypeEditors for a better user interface.

I have a problem with a custom TypeConverter for boolean properties. If I have this class:

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

and I create an instance and set it as SelectedObject in the PropertyGrid - everything is fine until the user double-clicks on the grid property element of the Flag property. After DoubleClick appears, this message: alt text
(source: tcks.wz.cz )

The TypeConverter class looks like this:

 public class BoolTypeConverter : System.ComponentModel.TypeConverter { public const string TEXT_TRUE = "On"; public const string TEXT_FALSE = "Off"; public const string TEXT_NONE = "< 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; } } 

This behavior is very confusing for users. How can I prevent this?

thanks

+6
c # type-conversion winforms propertygrid
source share
1 answer

Your GetStandardValues ​​() method is incorrect. It should return the type of the property, not the string:

 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; } 
+9
source share

All Articles