如何将通用枚举中的多个转换器参数传递给布尔转换器

时间:2013-09-18 05:38:15

标签: c# wpf xaml converter

我已经完成了这个How to bind RadioButtons to an enum?

并且接受这个问题的答案包含使用泛型Enum到布尔转换器。

我的问题是我在View中有两个单选按钮和一个枚举

 public Enum LinkType
   {
       A,
       B,
       C,
       D,
       E,
       F
    }

在ViewModel中,我有一个名为

的属性
public LinkType MyLinktype
{
  get;set;
}

如果ViewModel中枚举的属性具有A,C,E中的值,则第一个单选按钮可以为true,如果ViewModel中的枚举属性具有值,则第二个单选按钮可以为true。 B,d,F

那么,如何在通用EnumTo布尔转换器中的转换器参数中传递多个值,如下所示

 public class EnumBooleanConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string parameterString = parameter as string;
            if (parameterString == null)
                return DependencyProperty.UnsetValue;

            if (Enum.IsDefined(value.GetType(), value) == false)
                return DependencyProperty.UnsetValue;

            object parameterValue = Enum.Parse(value.GetType(), parameterString);

            return parameterValue.Equals(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string parameterString = parameter as string;
            if (parameterString == null)
                return DependencyProperty.UnsetValue;

            return Enum.Parse(targetType, parameterString);
        }

那么如果我想在XAML

中找到类似的内容,我必须在转换器中做出哪些改变
<RadioButton IsChecked="{Binding Path=MyLinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter=A,C,F}">Odd LinkType</RadioButton>

 <RadioButton IsChecked="{Binding Path=Mylinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter=B,D,E}">Even Link Type</RadioButton>

3 个答案:

答案 0 :(得分:9)

您可以在xaml中定义数组:

        <x:Array Type="LinkType" x:Key="ar">
            <LinkType>A</LinkType>
            <LinkType>B</LinkType>
        </x:Array>

然后将其作为参数传递

<RadioButton IsChecked="{Binding Path=MyLinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter={StaticResource ar}}">Odd LinkType</RadioButton>

您必须修改转换器,以便正确处理数组作为转换器参数。

答案 1 :(得分:2)

首先,我认为“Flags”属性是解决问题的关键:

[Flags]
public enum LinkType
{
    A=1,
    B=2,
    C=4,
    D=8,
    E=16
}

然后,我实现了这样的转换器:

public class LinkTypeToBoolCvt : IValueConverter
{
    #region | Members of IValueConverter |

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // please refer to the implementation of "CallBack" method
        throw new NotImplementedException();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null || parameter == null) return DependencyProperty.UnsetValue;

        var param= parameter.ToString();
        int result;
        if (int.TryParse(param,out result))
        {
            // ex: if the parameter is 11, the result will be "A|B|D"
            return result;
        }
        else
        {
            // ex: if the parameter is "A|E", the result will be 17
            var enums = param.Split(new []{"|"}, StringSplitOptions.RemoveEmptyEntries);

            LinkType lt = 0;
            LinkType ltTemp = 0;

            foreach (var item in enums)
            {
                if (Enum.TryParse<LinkType>(item, out ltTemp)) lt |= ltTemp;
            }

            if (lt == 0) return DependencyProperty.UnsetValue;
            else return lt;
        }
    } 

    #endregion
}

而且,在Xaml中你可以像这样使用它:

<RadioButton IsChecked="{Binding .MyLinkType,Converter={StaticResource LinkTypeToBoolCvt},ConverterParameter=11}" />

也是这样的:

<RadioButton IsChecked="{Binding .MyLinkType,Converter={StaticResource LinkTypeToBoolCvt},ConverterParameter=A|B|D}" />

如果您不使用“Flags”属性,则无法将结果如“A | B | D”传回模型。

最后,我应该为我可怜的英语道歉。 ^ - ^

答案 2 :(得分:1)

您可以将以下枚举用于布尔转换器

 [ValueConversion(typeof(Enum), typeof(bool))]
 public class EnumToBooleanConverter : IValueConverter
 {
   public object Convert(object value,
                      Type targetType,
                      object parameter,
                      CultureInfo culture)
       {
         if (
             (value == null) 
             || 
             (!(value is Enum))
             ||
             (parameter == null)
             )
                {
                   return false;
                }

  foreach (Enum paramValue in ParseObjectToEnum(value.GetType(),
                                                parameter))
  {
    if (value.Equals(paramValue))
    {
      return true;
    } 
  }

  return false;
}



public object ConvertBack(object value,
                          Type targetType,
                          object parameter,
                          CultureInfo culture)
{
  object result = Binding.DoNothing;

  if ((bool)value)
  {
    Enum[] parsedValues = ParseObjectToEnum(targetType,
                                            parameter);
    if (parsedValues.Length > 0)
    {
      result = parsedValues[0];
    } 
  }
  return result;
} 


private static Enum[] ParseObjectToEnum(Type enumType,
                                        object value)
{
  var enumValue = value as Enum;
  if (enumValue != null)
  {
    return new[] { enumValue };
  }

  var str = value as string;
  if (string.IsNullOrEmpty(str))
  {
    throw new ArgumentException("parameter");
  }

  string[] strArray = str.Split(new[] { ';', ',' },
                                StringSplitOptions.RemoveEmptyEntries);
  var enumArray = new Enum[strArray.Length];
  for (int i = 0;
       i < strArray.Length;
       i++)
  {
    enumArray[i] = (Enum)Enum.Parse(enumType,
                                    strArray[i],
                                    true);
  }

  return enumArray;
} 

}

并且在xaml中你可以像

一样使用
<RadioButton IsChecked="{Binding Path=MyLinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter=A;C;F}">Odd LinkType</RadioButton>

其中enumBooleanConverter是上面的转换器