2010-03-02 8 views
6

मैं अपने आवेदन में कुछ ऑब्जेक्ट्स संपादित करने के लिए PropertyGrid नियंत्रण का उपयोग कर रहा हूं। मैं बेहतर यूजर इंटरफेस के लिए कस्टम टाइप कन्वर्टर्स और टाइप एडिटर का उपयोग कर रहा हूं।संपत्ति ग्रिड आइटम और डबलक्लिक

मुझे बूलियन गुणों के लिए कस्टम टाइप कनवर्टर के साथ समस्या है। अगर मैं इस वर्ग है:

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

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

और मैं उदाहरण बना सकते हैं और PropertyGrid में SelectedObject के रूप में सेट - सभी जब तक उपयोगकर्ता संपत्ति ग्रिड आइटम प्रपत्र "चिह्नित करें" संपत्ति पर DoubleClicked ठीक है। बाद डबलक्लिक इस संदेश को उठाया है: 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 = "<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; 
    } 
} 

यह व्यवहार उपयोगकर्ताओं के लिए बहुत भ्रामक है। मैं यह कैसे रोक सकता हूँ?

धन्यवाद

उत्तर

8

आपका 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; 
} 
+0

बढ़िया, आप सही हैं। धन्यवाद! – TcKs

+1

@ निकोलस कैडिलैक, धन्यवाद! मैंने इस जवाब की तलाश में कितने घंटे बिताए! – Ben

+0

लगभग 8, मेरे मामले में>>। मुझे जेनेरिक एनम्स को परिवर्तित करने के लिए एक जटिल, जेनेरिक टाइप कनवर्टर विरासत में मिला, जिसमें यह समस्या थी, और मुझे बहुत कम विचार था कि कहां से शुरू करना है, प्रॉपर्टीग्रिड से रूपांतरण संभालने के लिए ज्यादातर आंतरिक .net जादू है। आखिर में यह पोस्ट मिला, जो वही था जो मैंने कामना की थी, मुझे घंटों पहले मिल गया था। धन्यवाद! (विशेष रूप से, यह [अंतर्निहित वस्तु -> स्ट्रिंग] का नक्शा बना रहा था, फिर GetStandardValues ​​कुंजी के बजाय मानचित्र में मान वापस कर रहा था। Yay।) – neminem

संबंधित मुद्दे