2011-08-18 3 views
8

나는 그러나 다음일반적인 Int-to-Enum 변환기를 만들 수 있습니까?

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

말을하고 int 값이 나는 (MyEnum)intValue 반환하는 Converter을 만들 수 알고 (int)MyEnum.Value

동일한 경우는 True으로 해결 가질 수 있도록하고 싶습니다 내 DataTriggers에서 사용하는 모든 Enum 형식에 대해 변환기를 만들어야합니다.

이런 종류의 기능을 제공하는 변환기를 만드는 일반적인 방법이 있습니까?

답변

4

값 대표 정수 작동하지 않기 때문에 비록 완벽한 해결책이 아니다 대신 내가 찾고 오전 열거 동일하고, 사실에 대한 평가/거 ~ Value

<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 메서드에 전달하여 적절한 열거 형식을 사용하고 적절한 값을 반환 할 수 있습니다.

이는 내가 난 그냥 내 ConverterParameter을 설정하는 데 필요한

그것을 알아 냈다고 생각 여러 열거의 이진 OR 작업이

+0

어떻게'Enum Type '을'Converter '안에 넣을 수 있습니까? – Rachel

3

사용자 정의 마크 업 확장 프로그램을 사용하여 값에 대한 enum을 int로 변환 할 수도 있습니다.

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

EnumToIntExtension

우리는이뿐만 아니라 과거에 몇 번하고 싶었던, 그래서 우리는 INT에 (여러 가지 확장 방법을 구축했습니다
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

전에 MarkupExtensions를 만난 적이 없습니다, 감사합니다! 아직 매일 새로운 무언가를 배우고 있습니다 :) – 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; 
    } 

이 구현은 [플래그] 속성으로 정의 된 내부 형식으로 열거 형뿐만 아니라 열거 처리.

6

재사용 가능한 방식으로 열거 형 값과 기본 내부 형식 사이에 변환기를 만들 수 있습니다. 즉, 열거 형마다 새 변환기를 정의 할 필요가 없습니다. 이에 대한 정보는 ConvertConvertBack으로 제공됩니다.

호출
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); 
    } 
} 

이 컨버터는 valuetargetType 값에 기초하여 순수 INT/ENUM 값 사이의 값의 타입을 튀긴다. 하드 코드 된 열거 유형이 없습니다.

관련 문제