2011-09-14 9 views
12

में गणना सदस्यों के प्रदर्शन नाम को संपादित करें मेरे पास एक संपत्ति ग्रिड है जिसका उपयोग मैं उपयोगकर्ताओं के लिए किसी भी प्लगइन के लिए ऑब्जेक्ट कॉन्फ़िगर करने में सक्षम होने के लिए कर रहा हूं जो मेरे आवेदन में उपयोग किए जाने के लिए लिखा गया है। मैं प्लगइन्स लेखन ComponentModel तो जैसे अपने सदस्यों के लिए गुण का उपयोग करने के डेवलपर्स को बताने के लिए सक्षम होने के लिए करना चाहते हैं:प्रॉपर्टीग्रिड

[CategoryAttribute("On Screen Display Settings"), 
DescriptionAttribute("Whether or not to show the session timer."), 
DisplayName("Show Session Timer")] 
public bool ShowTimer 
{ 
    get; 
    set; 
} 

यह काम करता है महान। अब मैं एक गणना के सदस्यों को भी संपादित करने में सक्षम होना चाहता हूं। अर्थात

public enum Resolution_ : byte 
{ 
    DCIF, 
    CIF, 
    QCIF, 
    [DisplayName("4CIF")] 
    CIF4, 
    [DisplayName("2CIF")] 
    CIF2 
} 

ताकि वे इतनी तरह PropertyGrid की सूची में प्रदर्शित होते हैं:

DCIF 
CIF 
QCIF 
CIF4 
CIF2 

किसी भी विवरण और प्रदर्शन नामों वे उन लोगों के साथ हो सकता है के साथ।

ऐसा लगता है कि मैं केवल गुणों, घटनाओं और विधियों के साथ ऐसा कर सकता हूं। क्या कोई जानता है कि मैं गणना के लिए यह कैसे कर सकता हूं?

उत्तर

14

आपको EnumConverter कक्षा बनाना होगा और ऐसा करने के लिए TypeConverter विशेषता के साथ अपनी संपत्ति को सजाने के लिए होगा।

देखें इस Using PropertyGrid in .NET, यह एक मजेदार उदाहरण है:

कल्पना कीजिए कि आप सूची में दो से अधिक आइटम चाहते हैं। बुलियन प्रकार पर्याप्त नहीं है; आपको enum में प्रत्येक तत्व के लिए नाम के साथ विवरण विशेषताओं को सेट करने की आवश्यकता है।

enum DrinkDoses { 
    [Description("Half of litre")] 
    litre, 
    [Description("One litre")] 
    oneLitre, 
    [Description("Two litres")] 
    twoLitre, 
    [Description("Three litres")] 
    threeLitres, 
    [Description("Four litres")] 
    fourLitres, 
    [Description("Death dose, five litres")] 
    fiveLitres 
} 

अन्य वर्ग आप प्रकार EnumConverter का उपयोग करने की आवश्यकता है।

class DrinkDosesConverter : EnumConverter { 
    private Type enumType; 

    public DrinkDosesConverter(Type type) : base(type) { 
    enumType = type; 
    } 

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destType) { 
    return destType == typeof(string); 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, 
            object value, Type destType) { 
    FieldInfo fi = enumType.GetField(Enum.GetName(enumType, value)); 
    DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, 
           typeof(DescriptionAttribute)); 
    if (dna != null) 
     return dna.Description; 
    else 
     return value.ToString(); 
    } 

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType) { 
    return srcType == typeof(string); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, 
            object value) { 
    foreach (FieldInfo fi in enumType.GetFields()) { 
     DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, 
            typeof(DescriptionAttribute)); 
     if ((dna != null) && ((string)value == dna.Description)) 
     return Enum.Parse(enumType, fi.Name); 
    } 
    return Enum.Parse(enumType, (string)value); 
    } 
} 

तीसरा, आप संपत्ति प्रदर्शित करने के लिए विशेषता TypeConverter सेट की जरूरत है।

class DrinkerDoses { 
    DrinkDoses doses; 
    [DisplayName("Doses")] 
    [Description("Drinker doses")] 
    [Category("Alcoholics drinking")] 
    [TypeConverter(typeof(DrinkDosesConverter))] 
    public DrinkDoses Doses { 
    get { return doses; } 
    set { doses = value; } 
    } 
    int dataInt; 
    public int DataInt { 
    get { return dataInt; } 
    set { dataInt = value; } 
    } 
} 
+0

धन्यवाद! वह यह था। मुझे नहीं पता क्यों, लेकिन Google और मुझे एक घंटे के साथ अभी भी वह लेख नहीं मिला। –

+0

अच्छा, मैं पहले प्रॉपर्टीग्रिड के साथ अपनी लड़ाई में एनम कनवर्टर में नहीं आया हूं। –

+0

हाइपरलिंक ".NET में PropertyGrid का उपयोग करना" अभी सही नहीं है। –

3

आप संपत्ति जिसका प्रकार अपने गणन है के लिए एक कस्टम TypeConverter कार्यान्वयन देते हैं और GetStandardValuesSupported और GetStandardValues ओवरराइड मदों की एक कस्टम सूची वापस जाने के लिए PropertyGrid में ड्रॉप-डाउन सूची में दिखाने के लिए कर सकते हैं। इसके बाद आप कनवर्टफ्रॉम/कनवर्ट करने के तरीकों को अपने गणना प्रकार से/परिवर्तित करने वाले मानों को संभालने के लिए ओवरराइड कर सकते हैं।

आप GetStandardValuesExclusive ओवरराइड भी कर सकते हैं और इसे "सत्य" वापस कर सकते हैं ताकि उपयोगकर्ता संपत्ति मूल्य में कुछ भी टाइप न कर सके।

तो, कुछ इस तरह:

public class MyTypeConverter : TypeConverter 
{ 
    //Override GetStandardValuesExclusive, 
    //GetStandardValues and GetStandardValuesSupported 
} 

public class SomeClass 
{ 
    [TypeConverter(typeof(MyTypeConverter))] 
    public Resolution SomePropertry 
    { 
     ... 
    } 
} 

GetStandardValues ​​/ ConvertFrom/ConvertTo अपने क्रियान्वयन की आप तो DisplayNameAttribute (या DescriptionAttribute, जो और अधिक इस कार्य के लिए उपयुक्त हो सकता है) बाहर निकलने के लिए प्रतिबिंब इस्तेमाल कर सकते हैं में गुण विभिन्न enum सदस्यों को दिखाने के लिए वस्तुओं की सूची हार्ड कोडिंग के बजाय पाठ दिखाने के लिए।

4

मैंने जवाब दिया here इसका एक उदाहरण है।

/// <summary> 
/// This attribute is used to represent a string value 
/// for a value in an enum. 
/// </summary> 
public class StringValueAttribute : Attribute { 

    #region Properties 

    /// <summary> 
    /// Holds the stringvalue for a value in an enum. 
    /// </summary> 
    public string StringValue { get; protected set; } 

    #endregion 

    #region Constructor 

    /// <summary> 
    /// Constructor used to init a StringValue Attribute 
    /// </summary> 
    /// <param name="value"></param> 
    public StringValueAttribute(string value) { 
     this.StringValue = value; 
    } 

    #endregion 

} 

public static class MyExtension 
{ 
    public static string GetStringValue(this Enum value) 
    { 
     // Get the type 
     Type type = value.GetType(); 

     // Get fieldinfo for this type 
     FieldInfo fieldInfo = type.GetField(value.ToString()); 

     // Get the stringvalue attributes 
     StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
      typeof(StringValueAttribute), false) as StringValueAttribute[]; 

     // Return the first if there was a match. 
     return attribs.Length > 0 ? attribs[0].StringValue : null; 
    } 

    public static String[] GetEnumNames(Type t) 
    { 
     Array enumValueArray= Enum.GetValues(t); 

     string[] enumStrings = new String[enumValueArray.Length]; 
     for(int i = 0; i< enumValueArray.Length; ++i) 
     { 
      enumStrings[i] = GetStringValue((test)enumValueArray.GetValue(i)); 
     } 

     return enumStrings; 
    } 
} 

enum test 
{ 
    [StringValue("test ONE")] 
    test1, 
    [StringValue("test TWO")] 
    test2 
} 
1

यह भी काम करने के लिए लगता है:: यहाँ कि उदाहरण से विशिष्ट कोड है कि आप चाहते हैं

[AttributeUsage(AttributeTargets.Field)] 
public class EnumDisplayNameAttribute : System.ComponentModel.DisplayNameAttribute 
{ 
    public EnumDisplayNameAttribute(string data) : base(data) { } 
} 

public enum Resolution_ : byte 
{ 
    DCIF, 
    CIF, 
    QCIF, 
    [EnumDisplayName("4CIF")] 
    CIF4, 
    [EnumDisplayName("2CIF")] 
    CIF2 
} 

अवयव प्रतिबिंब के माध्यम से एक DisplayName विशेषता की तलाश में एक मिल जाएगा, और जहाँ तक मैं कर सकते हैं यह काम बताओ। क्या कोई कारण है कि यह एक बुरा विचार क्यों हो सकता है?

+0

मुझे इस विचार की सादगी पसंद है, लेकिन दुर्भाग्य से यह मेरे लिए काम नहीं करता है (हालांकि, मैं विजुअल स्टूडियो विकल्प पेज बना रहा हूं, हालांकि, वेनिला प्रॉपर्टीग्रिड्स नहीं)। – Cameron

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