Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property grid item and DoubleClick

I'm using PropertyGrid control for editing some objects in my application. I'm using custom TypeConverters and TypeEditors for better user interface.

I have problem with 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 instance and set it as SelectedObject in PropertyGrid - all is fine until the user DoubleClicked on property grid item form "Flag" property. After DoubleClick is raised this message:alt text
(source: tcks.wz.cz)

The TypeConverter class looks:

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 behaviour is very confusing for users. How can I prevent it?

Thanks

like image 625
TcKs Avatar asked Mar 02 '10 10:03

TcKs


1 Answers

Your GetStandardValues() method is wrong. It must return the property type, not strings:

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;
}
like image 94
Nicolas Cadilhac Avatar answered Sep 18 '22 16:09

Nicolas Cadilhac