À titre d'exemple, prenez le code suivant:
public enum ExampleEnum { FooBar, BarFoo }
public class ExampleClass : INotifyPropertyChanged
{
private ExampleEnum example;
public ExampleEnum ExampleProperty
{ get { return example; } { /* set and notify */; } }
}
Je veux un pour lier la propriété ExampleProperty à un ComboBox, afin qu'il affiche les options "FooBar" et "BarFoo" et fonctionne en mode TwoWay. Idéalement, je veux que ma définition ComboBox ressemble à ceci:
<ComboBox ItemsSource="What goes here?" SelectedItem="{Binding Path=ExampleProperty}" />
Actuellement, j'ai des gestionnaires pour les événements ComboBox.SelectionChanged et ExampleClass.PropertyChanged installés dans ma fenêtre où je fais la liaison manuellement.
Existe-t-il une meilleure ou une sorte de méthode canonique? Utiliseriez-vous habituellement des convertisseurs et comment rempliriez-vous le ComboBox avec les bonnes valeurs? Je ne veux même pas commencer avec i18n pour le moment.
Éditer
Il a donc été répondu à une question: comment remplir le ComboBox avec les bonnes valeurs.
Récupérez les valeurs Enum sous forme de liste de chaînes via un ObjectDataProvider à partir de la méthode statique Enum.GetValues:
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="ExampleEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="ExampleEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Cela, je peux l'utiliser comme un ItemsSource pour mon ComboBox:
<ComboBox ItemsSource="{Binding Source={StaticResource ExampleEnumValues}}"/>
Réponses:
Vous pouvez créer une extension de balisage personnalisée.
Exemple d'utilisation:
En haut de votre XAML:
puis...
Et la mise en œuvre ...
la source
ItemsSource
param. Afin de garder la vue et le modèle découplés, je devrais créer une copie de l'énumération dans le ViewModel et coder ViewModel pour traduire entre les deux ... Ce qui rendrait la solution plus simple. Ou existe-t-il un moyen de fournir le type lui-même à partir de ViewModel?Dans le viewmodel, vous pouvez avoir:
En XAML, le
ItemSource
se lie àMyEnumTypeValues
etSelectedItem
se lie àSelectedMyEnumType
.la source
Je préfère ne pas utiliser le nom d'énumération dans l'interface utilisateur. Je préfère utiliser une valeur différente pour user (
DisplayMemberPath
) et différente pour value (enum dans ce cas) (SelectedValuePath
). Ces deux valeurs peuvent être regroupéesKeyValuePair
et stockées dans le dictionnaire.XAML
C #
EDIT: Compatible avec le modèle MVVM.
la source
Enum.GetValues
, mais cela ne résoudrait pas la partie des noms à afficher. En fin de compte, et surtout si I18n est implémenté, vous devrez de toute façon modifier manuellement les éléments si l'énumération change. Mais les énumérations ne sont pas censées changer souvent, voire pas du tout, n'est-ce pas? +1public Dictionary<ExampleEnum, string> ExampleEnumsWithCaptions { get; } = new Dictionary<ExampleEnum, string>() { {ExampleEnum.FooBar, "Foo Bar"}, {ExampleEnum.BarFoo, "Reversed Foo Bar"}, //{ExampleEnum.None, "Hidden in UI"}, };
Je ne sais pas si c'est possible en XAML uniquement, mais essayez ce qui suit:
Donnez un nom à votre ComboBox pour pouvoir y accéder dans le code derrière: "typesComboBox1"
Maintenant, essayez ce qui suit
la source
Sur la base de la réponse acceptée mais maintenant supprimée fournie par ageektrapped, j'ai créé une version allégée sans certaines des fonctionnalités les plus avancées. Tout le code est inclus ici pour vous permettre de le copier-coller et de ne pas être bloqué par link-rot.
J'utilise le
System.ComponentModel.DescriptionAttribute
qui est vraiment destiné aux descriptions de temps de conception. Si vous n'aimez pas utiliser cet attribut, vous pouvez créer le vôtre, mais je pense que l'utilisation de cet attribut fait vraiment le travail. Si vous n'utilisez pas l'attribut, le nom sera par défaut le nom de la valeur d'énumération dans le code.Voici la classe utilisée comme source des éléments:
Vous pouvez l'utiliser en XAML comme ceci:
la source
Utilisez ObjectDataProvider:
puis liez à la ressource statique:
Trouvez cette solution sur ce blog
la source
Converter
énumération chaîne.Ma façon préférée de le faire est de
ValueConverter
faire en sorte que ItemsSource et SelectedValue se lient tous les deux à la même propriété. Cela ne nécessite aucune propriété supplémentaire pour garder votre ViewModel agréable et propre.Et la définition du convertisseur:
Ce convertisseur fonctionnera avec n'importe quelle énumération.
ValueDescription
est juste une classe simple avec uneValue
propriété et uneDescription
propriété. Vous pouvez tout aussi facilement utiliser unTuple
avecItem1
etItem2
, ouKeyValuePair
avecKey
etValue
au lieu de Valeur et description ou toute autre classe de votre choix tant qu'il a peut contenir une valeur enum et une description de chaîne de cette valeur enum.la source
ValueDescription
classe, laDescription
propriété peut être omise si elle n'est pas nécessaire. Une classe simple avec seulementValue
propriété fonctionne aussi!.Select(e => e.ToString())
-à- dire au lieu d'utiliser laValueDescription
classe.ValueDescription
aussi, unKeyValuePair
pourrait être utilisé, comme indiqué iciVoici une solution générique utilisant une méthode d'assistance. Cela peut également gérer une énumération de tout type sous-jacent (octet, sbyte, uint, long, etc.)
Méthode d'assistance:
Voir le modèle:
Boîte combo:
la source
vous pouvez envisager quelque chose comme ça:
définissez un style pour le bloc de texte ou tout autre contrôle que vous souhaitez utiliser pour afficher votre énumération:
définir votre style pour ComboBoxItem
ajoutez une zone de liste déroulante et chargez-la avec vos valeurs d'énumération:
si votre énumération est volumineuse, vous pouvez bien sûr faire de même dans le code, en épargnant beaucoup de dactylographie. j'aime cette approche, car elle facilite la localisation - vous définissez tous les modèles une fois, puis vous ne mettez à jour que vos fichiers de ressources de chaîne.
la source
Si vous utilisez un MVVM, sur la base de la réponse @rudigrobler, vous pouvez effectuer les opérations suivantes:
Ajoutez la propriété suivante à la classe ViewModel
Ensuite, dans le XAML, procédez comme suit:
la source
Il s'agit d'une
DevExpress
réponse spécifique basée sur la réponse la plus votée deGregor S.
(actuellement, elle compte 128 voix).Cela signifie que nous pouvons garder le style cohérent dans toute l'application:
Malheureusement, la réponse originale ne fonctionne pas avec un
ComboBoxEdit
de DevExpress sans quelques modifications.Tout d'abord, le XAML pour
ComboBoxEdit
:Inutile de dire que vous devrez pointer
xamlExtensions
vers l'espace de noms qui contient la classe d'extension XAML (définie ci-dessous):Et nous devons pointer
myEnum
vers l'espace de noms qui contient l'énumération:Ensuite, l'énumération:
Le problème avec le XAML est que nous ne pouvons pas l'utiliser
SelectedItemValue
, car cela génère une erreur car le setter est inaccessible (peu d'oubli de votre part,DevExpress
). Nous devons donc modifier notreViewModel
pour obtenir la valeur directement à partir de l'objet:Pour être complet, voici l'extension XAML de la réponse d'origine (légèrement renommée):
Avertissement: je n'ai aucune affiliation avec DevExpress. Telerik est également une excellente bibliothèque.
la source
Essayez d'utiliser
la source
J'ai créé un projet CodePlex open source qui fait cela. Vous pouvez télécharger le package NuGet ici .
la source