2011-08-18 15 views
8

मैंक्या एक सामान्य इंट-टू-एनम कनवर्टर बनाना संभव है?

<DataTrigger Binding="{Binding SomeIntValue}" 
      Value="{x:Static local:MyEnum.SomeValue}"> 

कहने के लिए और अगर int मूल्य (int)MyEnum.Value

मैं जानता हूँ कि मैं एक Converter कि (MyEnum)intValue रिटर्न कर सकता है के बराबर होता है यह True के रूप में हल करने में सक्षम होना चाहते हैं, फिर भी तो मुझे अपने डेटा ट्रिगर्स में उपयोग किए जाने वाले प्रत्येक एनम प्रकार के लिए एक कनवर्टर बनाना होगा।

क्या कनवर्टर बनाने का एक सामान्य तरीका है जो मुझे इस तरह की कार्यक्षमता देगा?

उत्तर

4

को महत्व देता है मुझे लगता है कि मैं इसे समझ बाहर

मैं बस अपना ConverterParameter सेट करने के लिए आवश्यक साथ काम नहीं करेंगे एक आदर्श समाधान नहीं है बजाय Value Enum मैं देख रहा हूँ करने के लिए बराबर है, और यह सच है के लिए मूल्यांकन/असत्य की

<DataTrigger Value="True" 
      Binding="{Binding SomeIntValue, 
       Converter={StaticResource IsIntEqualEnumConverter}, 
       ConverterParameter={x:Static local:MyEnum.SomeValue}}"> 

कनवर्टर

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    if (parameter == null || value == null) return false; 

    if (parameter.GetType().IsEnum && value is int) 
    { 
     return (int)parameter == (int)value; 
    } 
    return false; 
} 
0

आप int मान पर एक ToString() कर सकते हैं और फिर उसे स्थिर Enum.Parse या Enum.TryParse विधि में पास कर सकते हैं जो आपके द्वारा की जाने वाली enum प्रकार लेता है और उपयुक्त मान देता है।

यह हालांकि, क्योंकि यह पूर्णांकों कि प्रतिनिधित्व एकाधिक enum की बाइनरी Oring

+0

मैं 'कनवर्टर' के अंदर एनम प्रकार कैसे प्राप्त करूं? – Rachel

3

आप एक कस्टम मार्कअप एक्सटेंशन का उपयोग कर मूल्य के लिए int में intum को घुमा सकते हैं।

उदाहरण

<DataTrigger Binding="{Binding Path=MyNumber}" 
      Value="{Markup:EnumToInt {x:Static Visibility.Visible}}"> 

EnumToIntExtension

public class EnumToIntExtension : MarkupExtension 
{ 
    public object EnumValue 
    { 
     get; 
     set; 
    } 
    public EnumToIntExtension(object enumValue) 
    { 
     this.EnumValue = enumValue; 
    } 
    public override object ProvideValue(IServiceProvider provider) 
    { 
     if (EnumValue != null && EnumValue is Enum) 
     { 
      return System.Convert.ToInt32(EnumValue); 
     } 
     return -1; 
    } 
} 
+0

मुझे पहले मार्कअप एक्सटेंशन का सामना नहीं हुआ है, धन्यवाद! अभी भी कुछ नया सीखना :) – Rachel

+0

वास्तव में वही है, मैंने अभी उनका उपयोग करना शुरू कर दिया है और वे काफी आसान हो सकते हैं :) –

1

हम इस अतीत में कई बार के रूप में अच्छी तरह से करना चाहता था, इसलिए हम कई विस्तार तरीकों (बनाया पूर्णांक पर, लंबे, आदि) हमें मदद करने के लिए। इन सब के मूल में एक भी स्थिर सामान्य TryAsEnum विधि में कार्यान्वित किया जाता:

/// <summary> 
    /// Helper method to try to convert a value to an enumeration value. 
    /// 
    /// If <paramref name="value"/> is not convertable to <typeparam name="TEnum"/>, an exception will be thrown 
    /// as documented by Convert.ChangeType. 
    /// </summary> 
    /// <param name="value">The value to convert to the enumeration type.</param> 
    /// <param name="outEnum">The enumeration type value.</param> 
    /// <returns>true if value was successfully converted; false otherwise.</returns> 
    /// <exception cref="InvalidOperationException">Thrown if <typeparamref name="TEnum"/> is not an enum type. (Because we can't specify a generic constraint that T is an Enum.)</exception> 
    public static bool TryAsEnum<TValue, TEnum>(TValue value, out TEnum outEnum) where TEnum : struct 
    { 
     var enumType = typeof(TEnum); 

     if (!enumType.IsEnum) 
     { 
      throw new InvalidOperationException(string.Format("{0} is not an enum type.", enumType.Name)); 
     } 

     var valueAsUnderlyingType = Convert.ChangeType(value, Enum.GetUnderlyingType(enumType)); 

     if (Enum.IsDefined(enumType, valueAsUnderlyingType)) 
     { 
      outEnum = (TEnum) Enum.ToObject(enumType, valueAsUnderlyingType); 
      return true; 
     } 

     // IsDefined returns false if the value is multiple composed flags, so detect and handle that case 

     if(enumType.GetCustomAttributes(typeof(FlagsAttribute), inherit: true).Any()) 
     { 
      // Flags attribute set on the enum. Get the enum value. 
      var enumValue = (TEnum)Enum.ToObject(enumType, valueAsUnderlyingType); 

      // If a value outside the actual enum range is set, then ToString will result in a numeric representation (rather than a string one). 
      // So if a number CANNOT be parsed from the ToString result, we know that only defined values have been set. 
      decimal parseResult; 
      if(!decimal.TryParse(enumValue.ToString(), out parseResult)) 
      { 
       outEnum = enumValue; 
       return true; 
      } 
     } 

     outEnum = default(TEnum); 
     return false; 
    } 

इस कार्यान्वयन संभालती [झंडे] विशेषता के साथ परिभाषित किसी भी अंतर्निहित प्रकार के साथ Enums, साथ ही enums।

6

एनम मूल्यों और उनके अंतर्निहित अभिन्न प्रकारों के बीच कनवर्टर बनाना पुन: प्रयोज्य तरीके से बनाना संभव है - यानी, आपको प्रत्येक enum प्रकारों के लिए एक नया कनवर्टर परिभाषित करने की आवश्यकता नहीं है। इसके लिए Convert और ConvertBack पर पर्याप्त जानकारी प्रदान की गई है।

public sealed class BidirectionalEnumAndNumberConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) 
      return null; 

     if (targetType.IsEnum) 
     { 
      // convert int to enum 
      return Enum.ToObject(targetType, value); 
     } 

     if (value.GetType().IsEnum) 
     { 
      // convert enum to int 
      return System.Convert.ChangeType(
       value, 
       Enum.GetUnderlyingType(value.GetType())); 
     } 

     return null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     // perform the same conversion in both directions 
     return Convert(value, targetType, parameter, culture); 
    } 
} 

जब लागू, इस कनवर्टर value और targetType मूल्यों पर विशुद्ध रूप से आधारित पूर्णांक/enum मूल्य के बीच मान का प्रकार flips। कोई कठोर कोडित enum प्रकार नहीं हैं।

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