2010-03-02 12 views
6

Uygulamamdaki bazı nesneleri düzenlemek için PropertyGrid denetimini kullanıyorum. Daha iyi bir kullanıcı arayüzü için özel TypeConverters ve TypeEditors kullanıyorum.Özellik kılavuz öğesi ve DoubleClick

Boole özellikleri için özel TypeConverter ile ilgili bir sorunum var. Bu dersten varsa:

public class MyClass { 
    public string Name { get; set; } 

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

ve ben örneğini oluşturmak ve PropertyGrid içinde SelectedObject olarak ayarlayın - kullanıcı özelliği ızgara öğesi formu "Bayrak" mülkiyet DoubleClicked kadar tüm gayet iyi. DoubleClick bu mesajı yükseltilir sonra: alt text http://tcks.wz.cz/property_grid_error.PNG

TypeConverter sınıfı arar:

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; 
    } 
} 

Bu davranış kullanıcıları için çok kafa karıştırıcı. Bunu nasıl önleyebilirim?

Teşekkür

cevap

8

Kişisel GetStandardValues ​​() yöntemi yanlıştır. Özellik türünü döndürmelidir, dizeleri değil:

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; 
} 
+0

Harika, haklısınız. Teşekkürler! – TcKs

+1

@Nicolas Cadilhac, Teşekkürler! Bu cevabı sadece kaç saat harcadım? – Ben

+0

Yaklaşık 8, benim durumumda>.>. Ben bu sorun vardı jenerik enums, dönüştürmek için oldukça karmaşık, jenerik bir TypeConverter miras aldım ve bir PropertyGrid dönüşüm işlenmesi çoğunlukla iç. Net büyü verildiğinde, nerede başlamak için çok az fikri vardı. Sonunda bu yazıyı buldum, bu da tam olarak saat önce bulmayı dilediğim şeydi. Teşekkürler! (Özellikle, [altta yatan bir nesne -> dize] haritası oluşturuyordu, daha sonra GetStandardValues ​​anahtarlar yerine haritadaki değerleri döndürüyordu. Yay.) – neminem

İlgili konular