4 votes

Comment passer plusieurs paramètres de conversion dans un convertisseur générique Enum to Boolean ?

Je suis passé par là Comment lier les RadioButtons à un enum ?

et la réponse acceptée à cette question contient l'utilisation d'un convertisseur générique Enum vers Boolean.

Mon problème est que j'ai deux boutons radio dans la vue et un enum.

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

Dans le ViewModel, j'ai une propriété appelée

public LinkType MyLinktype
{
  get;set;
}

mon premier bouton radio peut être vrai si la propriété de l'enum dans le ViewModel a une valeur parmi A, C, E et le second bouton radio peut être vrai si la propriété de l'enum dans le ViewModel a une valeur parmi B,D,F

Alors, comment puis-je passer plusieurs valeurs dans le paramètre du convertisseur dans le convertisseur générique EnumTo Boolean Converter qui est le suivant

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

Quels sont donc les changements que je dois faire dans le convertisseur si je veux quelque chose comme ceci dans le 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>

9voto

Nikita Brizhak Points 1898

Vous pouvez définir un tableau dans le xaml :

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

Et ensuite le passer comme paramètre

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

Vous devrez corriger votre convertisseur afin de gérer correctement le tableau comme paramètre du convertisseur.

3voto

lyphoon Points 46

Tout d'abord, je pense que l'attribut "Flags" est la clé pour résoudre le problème :

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

Et ensuite, j'implémente le convertisseur comme ceci :

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
}

Et, dans Xaml, vous pouvez l'utiliser comme ceci :

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

J'aime aussi ça :

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

si vous n'utilisez pas l'attribut "Flags", vous ne pouvez pas transférer le résultat comme "A|B|D" dans votre modèle.

Enfin, je dois m'excuser pour mon mauvais anglais. ^-^

1voto

Mohd Ahmed Points 1362

Vous pouvez utiliser le convertisseur enum en boolean suivant

 [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;
} 

}

et dans le xaml vous pouvez utiliser comme

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

où enumBooleanConverter est le convertisseur ci-dessus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X