title: Property grid item and DoubleClick
body: <p>I'm using PropertyGrid control for editing some objects in my application. I'm using custom TypeConverters and TypeEditors for better user interface.</p>
  
  <p>I have problem with custom TypeConverter for boolean properties. If I have this class:</p>
  
  <pre><code>public class MyClass {
      public string Name { get; set; }
  
      [System.ComponentModel.TypeConverter( typeof( BoolTypeConverter ) )]
      public bool Flag { get; set; }
  }
  </code></pre>
  
  <p>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:<a href="https://i.stack.imgur.com/Am4bO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Am4bO.png" alt="alt text"></a><br>
  <sub>(source: <a href="http://tcks.wz.cz/property_grid_error.PNG" rel="nofollow noreferrer">tcks.wz.cz</a>)</sub>  </p>
  
  <p>The TypeConverter class looks:</p>
  
  <pre><code>public class BoolTypeConverter : System.ComponentModel.TypeConverter {
      public const string TEXT_TRUE = "On";
      public const string TEXT_FALSE = "Off";
      public const string TEXT_NONE = "&lt; none &gt;";
  
      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;
      }
  }
  </code></pre>
  
  <p>This behaviour is very confusing for users. How can I prevent it?</p>
  
  <p>Thanks</p>