web-dev-qa-db-fra.com

Comment lier une enum à un contrôle de liste déroulante dans WPF?

J'essaie de trouver un exemple simple où les énumérations sont montrées telles quelles. Tous les exemples que j'ai vus essaient d'ajouter des chaînes d'affichage d'apparence agréable, mais je ne veux pas de cette complexité.

En gros, j'ai une classe qui contient toutes les propriétés que je lie, en définissant d'abord le DataContext sur cette classe, puis en spécifiant la liaison comme ceci dans le fichier xaml:

<ComboBox ItemsSource="{Binding Path=EffectStyle}"/>

Mais cela ne montre pas les valeurs enum dans le ComboBox en tant qu'éléments.

166
Joan Venge

Vous pouvez le faire à partir de code en plaçant le code suivant dans le gestionnaire d'événements Window Loaded, par exemple:

yourComboBox.ItemsSource = Enum.GetValues(typeof(EffectStyle)).Cast<EffectStyle>();

Si vous devez le lier en XAML, vous devez utiliser ObjectDataProvider pour créer un objet disponible en tant que source de liaison:

<Window x:Class="YourNamespace.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;Assembly=mscorlib"
        xmlns:StyleAlias="clr-namespace:Motion.VideoEffects">
    <Window.Resources>
        <ObjectDataProvider x:Key="dataFromEnum" MethodName="GetValues"
                            ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="StyleAlias:EffectStyle"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <ComboBox ItemsSource="{Binding Source={StaticResource dataFromEnum}}"
                  SelectedItem="{Binding Path=CurrentEffectStyle}" />
    </Grid>
</Window>

Attirez l'attention sur le code suivant:

xmlns:System="clr-namespace:System;Assembly=mscorlib"
xmlns:StyleAlias="clr-namespace:Motion.VideoEffects"

Guidez comment mapper un espace de noms et une assemblée que vous pouvez lire sur MSDN .

279
Kyrylo M

J'aime que tous les objets que je lie soient définis dans mon ViewModel, aussi j'essaie d'éviter d'utiliser <ObjectDataProvider> dans le xaml lorsque cela est possible.

Ma solution n'utilise aucune donnée définie dans la vue et aucun code-behind. Un DataBinding uniquement, un ValueConverter réutilisable, une méthode permettant d’obtenir une collection de descriptions pour tout type Enum et une seule propriété du ViewModel à laquelle se lier.

Lorsque je veux lier un Enum à un ComboBox, le texte que je veux afficher ne correspond jamais aux valeurs de Enum, aussi j'utilise l'attribut [Description()] pour le lui donner. texte que je veux réellement voir dans le ComboBox. Si j'avais une énumération de classes de personnages dans un jeu, cela ressemblerait à ceci:

public enum PlayerClass
{
  // add an optional blank value for default/no selection
  [Description("")]
  NOT_SET = 0,
  [Description("Shadow Knight")]
  SHADOW_KNIGHT,
  ...
}

J'ai d'abord créé une classe d'assistance avec quelques méthodes pour traiter les énumérations. Une méthode obtient une description pour une valeur spécifique, l'autre méthode obtient toutes les valeurs et leurs descriptions pour un type.

public static class EnumHelper
{
  public static string Description(this Enum value)
  {
    var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (attributes.Any())
      return (attributes.First() as DescriptionAttribute).Description;

    // If no description is found, the least we can do is replace underscores with spaces
    // You can add your own custom default formatting logic here
    TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
    return ti.ToTitleCase(ti.ToLower(value.ToString().Replace("_", " ")));
  }

  public static IEnumerable<ValueDescription> GetAllValuesAndDescriptions(Type t)
  {
    if (!t.IsEnum)
      throw new ArgumentException($"{nameof(t)} must be an enum type");

    return Enum.GetValues(t).Cast<Enum>().Select((e) => new ValueDescription() { Value = e, Description = e.Description() }).ToList();
  }
}

Ensuite, nous créons un ValueConverter. L'héritage de MarkupExtension facilite son utilisation en XAML, évitant ainsi de le déclarer en tant que ressource.

[ValueConversion(typeof(Enum), typeof(IEnumerable<ValueDescription>))]
public class EnumToCollectionConverter : MarkupExtension, IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return EnumHelper.GetAllValuesAndDescriptions(value.GetType());
  }
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return null;
  }
  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    return this;
  }
}

Mon ViewModel n'a besoin que d'une propriété à laquelle mon View peut se lier à la fois pour le SelectedValue et ItemsSource de la liste déroulante:

private PlayerClass playerClass;

public PlayerClass SelectedClass
{
  get { return playerClass; }
  set
  {
    if (playerClass != value)
    {
      playerClass = value;
      OnPropertyChanged(nameof(SelectedClass));
    }
  }
}

Et enfin pour lier la vue ComboBox (en utilisant le ValueConverter dans la liaison ItemsSource ...).

<ComboBox ItemsSource="{Binding Path=SelectedClass, Converter={x:EnumToCollectionConverter}, Mode=OneTime}"
          SelectedValuePath="Value"
          DisplayMemberPath="Description"
          SelectedValue="{Binding Path=SelectedClass}" />

Pour implémenter cette solution, il vous suffit de copier ma classe EnumHelper et ma classe EnumToCollectionConverter. Ils travailleront avec tout enums. De plus, je ne l'ai pas inclus ici, mais la classe ValueDescription n'est qu'une simple classe avec 2 propriétés d'objet public, l'une appelée Value, l'autre Description. Vous pouvez le créer vous-même ou vous pouvez modifier le code pour utiliser un Tuple<object, object> ou KeyValuePair<object, object>

102
Nick

J'ai utilisé une autre solution en utilisant MarkupExtension.

  1. J'ai fait classe qui fournit les éléments source:

    public class EnumToItemsSource : MarkupExtension
    {
        private readonly Type _type;
    
        public EnumToItemsSource(Type type)
        {
            _type = type;
        }
    
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return Enum.GetValues(_type)
                .Cast<object>()
                .Select(e => new { Value = (int)e, DisplayName = e.ToString() });
        }
    }
    
  2. C'est presque tout ... Maintenant, utilisez-le dans XAML:

        <ComboBox DisplayMemberPath="DisplayName"
              ItemsSource="{persons:EnumToItemsSource {x:Type enums:States}}"
              SelectedValue="{Binding Path=WhereEverYouWant}"
              SelectedValuePath="Value" />
    
  3. Changez 'enums: States' en votre enum

45
tom.maruska

Utilisez ObjectDataProvider:

<ObjectDataProvider x:Key="enumValues"
   MethodName="GetValues" ObjectType="{x:Type System:Enum}">
      <ObjectDataProvider.MethodParameters>
           <x:Type TypeName="local:ExampleEnum"/>
      </ObjectDataProvider.MethodParameters>
 </ObjectDataProvider>

puis lier à une ressource statique:

ItemsSource="{Binding Source={StaticResource enumValues}}"

basé sur cet article

21
druss

La réponse de Nick m'a vraiment aidé, mais je me suis rendu compte que cela pourrait être légèrement modifié, afin d'éviter une classe supplémentaire, ValueDescription. Je me suis rappelé qu'il existe déjà une classe KeyValuePair dans le framework, elle peut donc être utilisée à la place.

Le code ne change que légèrement:

public static IEnumerable<KeyValuePair<string, string>> GetAllValuesAndDescriptions<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable
    {
        if (!typeof(TEnum).IsEnum)
        {
            throw new ArgumentException("TEnum must be an Enumeration type");
        }

        return from e in Enum.GetValues(typeof(TEnum)).Cast<Enum>()
               select new KeyValuePair<string, string>(e.ToString(),  e.Description());
    }


public IEnumerable<KeyValuePair<string, string>> PlayerClassList
{
   get
   {
       return EnumHelper.GetAllValuesAndDescriptions<PlayerClass>();
   }
}

et enfin le XAML:

<ComboBox ItemSource="{Binding Path=PlayerClassList}"
          DisplayMemberPath="Value"
          SelectedValuePath="Key"
          SelectedValue="{Binding Path=SelectedClass}" />

J'espère que cela est utile aux autres.

9
Roger

Vous devrez créer un tableau des valeurs dans l'énum, ​​qui peut être créé en appelant System.Enum.GetValues ​​() , en lui transmettant la Type de l'énum que vous souhaitez. les articles de.

Si vous spécifiez ceci pour la propriété ItemsSource, elle doit alors être renseignée avec toutes les valeurs de l'énum. Vous voudrez probablement lier SelectedItem à EffectStyle (en supposant qu'il s'agisse d'une propriété du même enum qui contient la valeur actuelle).

8
Andy

Tous les messages ci-dessus ont manqué un tour simple. Il est possible, à partir de la liaison de SelectedValue, de savoir comment renseigner AUTOMAGIQUEMENT le ItemsSource afin que votre balise XAML soit juste.

<Controls:EnumComboBox SelectedValue="{Binding Fool}"/>

Par exemple, dans mon ViewModel, j'ai

public enum FoolEnum
    {
        AAA, BBB, CCC, DDD

    };


    FoolEnum _Fool;
    public FoolEnum Fool
    {
        get { return _Fool; }
        set { ValidateRaiseAndSetIfChanged(ref _Fool, value); }
    }

ValidateRaiseAndSetIfChanged est mon hook INPC. Le vôtre peut différer.

La mise en oeuvre d’EnumComboBox est la suivante, mais j’ai d’abord besoin d’un petit assistant pour obtenir mes chaînes et valeurs d’énumération.

    public static List<Tuple<object, string, int>> EnumToList(Type t)
    {
        return Enum
            .GetValues(t)
            .Cast<object>()
            .Select(x=>Tuple.Create(x, x.ToString(), (int)x))
            .ToList();
    }

et la classe principale (Notez que j'utilise ReactiveUI pour accrocher les changements de propriété via WhenAny)

using ReactiveUI;
using ReactiveUI.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Documents;

namespace My.Controls
{
    public class EnumComboBox : System.Windows.Controls.ComboBox
    {
        static EnumComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumComboBox), new FrameworkPropertyMetadata(typeof(EnumComboBox)));
        }

        protected override void OnInitialized( EventArgs e )
        {
            base.OnInitialized(e);

            this.WhenAnyValue(p => p.SelectedValue)
                .Where(p => p != null)
                .Select(o => o.GetType())
                .Where(t => t.IsEnum)
                .DistinctUntilChanged()
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(FillItems);
        }

        private void FillItems(Type enumType)
        {
            List<KeyValuePair<object, string>> values = new List<KeyValuePair<object,string>>();

            foreach (var idx in EnumUtils.EnumToList(enumType))
            {
                values.Add(new KeyValuePair<object, string>(idx.Item1, idx.Item2));
            }

            this.ItemsSource = values.Select(o=>o.Key.ToString()).ToList();

            UpdateLayout();
            this.ItemsSource = values;
            this.DisplayMemberPath = "Value";
            this.SelectedValuePath = "Key";

        }
    }
}

Vous devez également définir le style correctement dans Generic.XAML, sinon votre boîte de dialogue ne restituera rien et vous tirerez les cheveux.

<Style TargetType="{x:Type local:EnumComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
</Style>

et c'est ça. Cela pourrait évidemment être étendu pour supporter i18n mais rendrait le post plus long.

4
bradgonesurfing

Il y a beaucoup d'excellentes réponses à cette question et je soumets humblement la mienne. Je trouve que le mien est un peu plus simple et élégant. Il ne nécessite qu'un convertisseur de valeur.

Donné un enum ...

public enum ImageFormat
{
    [Description("Windows Bitmap")]
    BMP,
    [Description("Graphics Interchange Format")]
    GIF,
    [Description("Joint Photographic Experts Group Format")]
    JPG,
    [Description("Portable Network Graphics Format")]
    PNG,
    [Description("Tagged Image Format")]
    TIFF,
    [Description("Windows Media Photo Format")]
    WDP
}

et un convertisseur de valeur ...

public class ImageFormatValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ImageFormat format)
        {
            return GetString(format);
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string s)
        {
            return Enum.Parse(typeof(ImageFormat), s.Substring(0, s.IndexOf(':')));
        }
        return null;
    }

    public string[] Strings => GetStrings();

    public static string GetString(ImageFormat format)
    {
        return format.ToString() + ": " + GetDescription(format);
    }

    public static string GetDescription(ImageFormat format)
    {
        return format.GetType().GetMember(format.ToString())[0].GetCustomAttribute<DescriptionAttribute>().Description;

    }
    public static string[] GetStrings()
    {
        List<string> list = new List<string>();
        foreach (ImageFormat format in Enum.GetValues(typeof(ImageFormat)))
        {
            list.Add(GetString(format));
        }

        return list.ToArray();
    }
}

ressources...

    <local:ImageFormatValueConverter x:Key="ImageFormatValueConverter"/>

Déclaration XAML ...

    <ComboBox Grid.Row="9" ItemsSource="{Binding Source={StaticResource ImageFormatValueConverter}, Path=Strings}"
              SelectedItem="{Binding Format, Converter={StaticResource ImageFormatValueConverter}}"/>

Voir le modèle ...

    private ImageFormat _imageFormat = ImageFormat.JPG;
    public ImageFormat Format
    {
        get => _imageFormat;
        set
        {
            if (_imageFormat != value)
            {
                _imageFormat = value;
                OnPropertyChanged();
            }
        }
    }

Combobox résultant ...

ComboBox bound to enum

2
AQuirky
public class EnumItemsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!value.GetType().IsEnum)
            return false;

        var enumName = value.GetType();
        var obj = Enum.Parse(enumName, value.ToString());

        return System.Convert.ToInt32(obj);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Enum.ToObject(targetType, System.Convert.ToInt32(value));
    }
}

Vous devriez étendre la réponse de Rogers et Greg avec ce type de convertisseur de valeur Enum, si vous vous liez directement à des propriétés de modèle d'objet enum.

2
Ruberoid

Les applications universelles semblent fonctionner un peu différemment. il n'a pas toute la puissance d'un XAML complet. Ce qui a fonctionné pour moi est:

  1. J'ai créé une liste des valeurs enum en tant qu'énums (non convertis en chaînes ou en entiers) et lié le ComboBox ItemsSource à celui
  2. Ensuite, je pourrais lier l'objet ItemSelected de la ComboBox à ma propriété publique dont le type est l'énum en question.

Juste pour le plaisir, j'ai préparé une petite classe basée sur un modèle pour l'aider et je l'ai publiée dans pages d'échantillons MSDN . Les bits supplémentaires me permettent de remplacer éventuellement les noms des énumérations et de me laisser masquer certaines des énumérations. Mon code ressemble terriblement à celui de Nick (ci-dessus), ce que j'aurais aimé voir plus tôt.

Running the sample; it includes multiple twoway bindings to the enum

2
PESMITH_MSFT

Si vous vous liez à une propriété enum réelle sur votre ViewModel, et non à la représentation int d'une énumération, les choses deviennent compliquées. J'ai trouvé qu'il est nécessaire de se lier à la représentation sous forme de chaîne, PAS à la valeur int, comme cela est attendu dans tous les exemples ci-dessus.

Vous pouvez savoir si c'est le cas en liant une zone de texte simple à la propriété que vous souhaitez lier sur votre ViewModel. Si le texte est affiché, liez-vous à la chaîne. Si elle affiche un nombre, liez-vous à la valeur. Remarque J'ai utilisé l'affichage deux fois, ce qui serait normalement une erreur, mais c'est la seule façon de fonctionner.

<ComboBox SelectedValue="{Binding ElementMap.EdiDataType, Mode=TwoWay}"
                      DisplayMemberPath="Display"
                      SelectedValuePath="Display"
                      ItemsSource="{Binding Source={core:EnumToItemsSource {x:Type edi:EdiDataType}}}" />

Greg

1
Greg Gum

Explication simple et claire: http://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/

xmlns:local="clr-namespace:BindingEnums"
xmlns:sys="clr-namespace:System;Assembly=mscorlib"

...

<Window.Resources>
    <ObjectDataProvider x:Key="dataFromEnum" MethodName="GetValues"
                        ObjectType="{x:Type sys:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:Status"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

...

<Grid>
    <ComboBox HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="150"
              ItemsSource="{Binding Source={StaticResource dataFromEnum}}"/>
</Grid>
1
jlo-gmail

J'ai aimé réponse de tom.maruska , mais je devais prendre en charge tout type d'enum que mon modèle pourrait rencontrer à l'exécution. Pour cela, je devais utiliser une liaison pour spécifier le type à l'extension de balisage. J'ai pu travailler dans cette réponse de nicolay.anykienko afin de proposer une extension de balisage très flexible qui fonctionnerait dans tous les cas, à quoi je puisse penser. C'est consommé comme ça:

<ComboBox SelectedValue="{Binding MyEnumProperty}" 
          SelectedValuePath="Value"
          ItemsSource="{local:EnumToObjectArray SourceEnum={Binding MyEnumProperty}}" 
          DisplayMemberPath="DisplayName" />

La source de l'extension de balisage purée référencée ci-dessus:

class EnumToObjectArray : MarkupExtension
{
    public BindingBase SourceEnum { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        DependencyObject targetObject;
        DependencyProperty targetProperty;

        if (target != null && target.TargetObject is DependencyObject && target.TargetProperty is DependencyProperty)
        {
            targetObject = (DependencyObject)target.TargetObject;
            targetProperty = (DependencyProperty)target.TargetProperty;
        }
        else
        {
            return this;
        }

        BindingOperations.SetBinding(targetObject, EnumToObjectArray.SourceEnumBindingSinkProperty, SourceEnum);

        var type = targetObject.GetValue(SourceEnumBindingSinkProperty).GetType();

        if (type.BaseType != typeof(System.Enum)) return this;

        return Enum.GetValues(type)
            .Cast<Enum>()
            .Select(e => new { Value=e, Name = e.ToString(), DisplayName = Description(e) });
    }

    private static DependencyProperty SourceEnumBindingSinkProperty = DependencyProperty.RegisterAttached("SourceEnumBindingSink", typeof(Enum)
                       , typeof(EnumToObjectArray), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));

    /// <summary>
    /// Extension method which returns the string specified in the Description attribute, if any.  Oherwise, name is returned.
    /// </summary>
    /// <param name="value">The enum value.</param>
    /// <returns></returns>
    public static string Description(Enum value)
    {
        var attrs = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attrs.Any())
            return (attrs.First() as DescriptionAttribute).Description;

        //Fallback
        return value.ToString().Replace("_", " ");
    }
}
1
Hamish

J'ajoute mon commentaire (en VB, malheureusement, mais le concept peut facilement être reproduit en C # en un clin d'œil), car je devais simplement faire référence à cela et je n'aimais aucune des réponses, car elles étaient trop complexes. Cela ne devrait pas être aussi difficile.

Alors je suis venu avec un moyen plus facile. Lier les énumérateurs à un dictionnaire. Liez ce dictionnaire à la Combobox.

Ma combobox:

<ComboBox x:Name="cmbRole" VerticalAlignment="Stretch" IsEditable="False" Padding="2" 
    Margin="0" FontSize="11" HorizontalAlignment="Stretch" TabIndex="104" 
    SelectedValuePath="Key" DisplayMemberPath="Value" />

Mon code-behind. Espérons que cela aide quelqu'un d'autre.

Dim tDict As New Dictionary(Of Integer, String)
Dim types = [Enum].GetValues(GetType(Helper.Enumerators.AllowedType))
For Each x As Helper.Enumerators.AllowedType In types
    Dim z = x.ToString()
    Dim y = CInt(x)
    tDict.Add(y, z)
Next

cmbRole.ClearValue(ItemsControl.ItemsSourceProperty)
cmbRole.ItemsSource = tDict
0
Laki Politis

La solution de Nick peut être simplifiée davantage, sans rien d'extraordinaire, vous n'auriez besoin que d'un seul convertisseur:

[ValueConversion(typeof(Enum), typeof(IEnumerable<Enum>))]
public class EnumToCollectionConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var r = Enum.GetValues(value.GetType());
        return r;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

Vous l'utilisez ensuite où vous voulez que votre liste déroulante apparaisse:

<ComboBox ItemsSource="{Binding PagePosition, Converter={converter:EnumToCollectionConverter}, Mode=OneTime}"  SelectedItem="{Binding PagePosition}" />
0
Jack

En utilisant ReactiveUI, j'ai créé la solution alternative suivante. Ce n'est pas une solution tout-en-un élégante, mais je pense qu'elle est au moins lisible.

Dans mon cas, lier une liste de enum à un contrôle est un cas rare. Je n'ai donc pas besoin de faire évoluer la solution sur la base de code. Cependant, le code peut être rendu plus générique en changeant EffectStyleLookup.Item en Object. Je l'ai testé avec mon code, aucune autre modification n'est nécessaire. Ce qui signifie que la classe d'assistance unique pourrait être appliquée à n'importe quelle liste enum. Bien que cela réduirait sa lisibilité - ReactiveList<EnumLookupHelper> ne sonne pas très bien.

Utilisation de la classe d'assistance suivante:

public class EffectStyleLookup
{
    public EffectStyle Item { get; set; }
    public string Display { get; set; }
}

Dans le ViewModel, convertissez la liste des énumérations et exposez-la en tant que propriété:

public ViewModel : ReactiveObject
{
  private ReactiveList<EffectStyleLookup> _effectStyles;
  public ReactiveList<EffectStyleLookup> EffectStyles
  {
    get { return _effectStyles; }
    set { this.RaiseAndSetIfChanged(ref _effectStyles, value); }
  }

  // See below for more on this
  private EffectStyle _selectedEffectStyle;
  public EffectStyle SelectedEffectStyle
  {
    get { return _selectedEffectStyle; }
    set { this.RaiseAndSetIfChanged(ref _selectedEffectStyle, value); }
  }

  public ViewModel() 
  {
    // Convert a list of enums into a ReactiveList
    var list = (IList<EffectStyle>)Enum.GetValues(typeof(EffectStyle))
      .Select( x => new EffectStyleLookup() { 
        Item = x, 
        Display = x.ToString()
      });

    EffectStyles = new ReactiveList<EffectStyle>( list );
  }
}

Dans la ComboBox, utilisez la propriété SelectedValuePath pour vous lier à la valeur originale enum:

<ComboBox Name="EffectStyle" DisplayMemberPath="Display" SelectedValuePath="Item" />

Dans la vue, cela nous permet de lier l'original enum au SelectedEffectStyle du ViewModel, mais d'afficher la valeur ToString() dans le ComboBox:

this.WhenActivated( d =>
{
  d( this.OneWayBind(ViewModel, vm => vm.EffectStyles, v => v.EffectStyle.ItemsSource) );
  d( this.Bind(ViewModel, vm => vm.SelectedEffectStyle, v => v.EffectStyle.SelectedValue) );
});
0
Mitkins