2017-05-23 1 views
0

Jusqu'à présent, j'ai soemthing comme ceci:valeur personnalisée dans HTML.EnumDropDownListFor

public enum MyEnum 
{ 
    [Display(Name="FirstElement")] 
    element1 = 1, 
    [Display(Name="SecondElement")] 
    element2 = 2 
} 

Et dans la vue, si j'utiliser:

Html.EnumDropDownListFor(x=>x.EnumProperty) 

Tout en ayant:

public MyEnum EnumProperty {get;set;} 

Sur le modèle de vue, la liste déroulante fonctionne comme prévu (je vois FirstElement, et la valeur ci-jointe est element1)

Le problème est que je veux avoir un tableau de bord de la valeur, comme celui-ci:

public enum MyEnum 
{ 
    [Display(Name="FirstElement")] 
    element1 = 1, 
    [Display(Name="SecondElement")] 
    element2 = 2, 
    [Display(Name="Third")] 
    element-dashed = 3 
} 

Il ne fonctionne pas, comme cela est sans élément en pointillés une entrée valide. Cela ne fonctionnera pas non plus:

[Value("element-dashed")] 
[Display(Name="Third")] 
elementDashed = 3 
+0

Je pense que vous confondez ce qui est le code/données et ce qu'est l'interface utilisateur. Le simple fait que C# permette de telles choses dans l'interface utilisateur ne signifie pas que le code le supporte (par exemple des variables ou des types avec des tirets). Pourquoi voulez-vous une variable avec un tiret dedans (à ce stade, la variable/enum est données, pas quelque chose dans l'interface utilisateur) – Neil

+0

Je ne suis pas confus entre eux, je sais que le code ne supporte pas les tirets dans les variables, qui est ce qui cause le problème. Mais il est demandé/requis que j'ai un tiret dans la valeur lors de la sauvegarde, et les exigences proviennent de quelqu'un de non technique. Je pensais simplement remplacer "elementDashed" par "element-hashed" dans un mappeur lors de la sauvegarde, mais je cherchais un meilleur moyen si possible. –

+0

Je présume qu'à un certain point, cette valeur sera écrite dans une base de données, ou exportée vers un autre système 'externe'? Faites simplement le formatage requis ici. – Neil

Répondre

0

La réponse à votre question est simple. Mais cela mérite une explication, pour expliquer pourquoi c'est la réponse.

Il n'y a aucune raison fonctionnelle de vouloir un tiret dans une énumération.

Disons que j'ai une application de travail, qui contient votre ENUM:

public enum MyEnum 
{ 
    [Display(Name="FirstElement")] 
    element1 = 1, 
    [Display(Name="SecondElement")] 
    element2 = 2 
} 

Supposons que je change les noms de recenseur:

public enum MyEnum 
{ 
    [Display(Name="FirstElement")] 
    BatmanIsBruceWayne = 1, 
    [Display(Name="SecondElement")] 
    SupermanIsClarkKent = 2 
} 

Je suppose que chaque utilisation de l'ENUM en le code est également ajusté en conséquence. Si vous utilisez la méthode Rename dans VS (F2), c'est automatiquement le cas.

Rien n'a changé sur le fonctionnement de l'application. Fonctionnellement, le nom d'une énumération n'a pas d'importance.

public enum CardSuit { Hearts, Spades, Diamonds, Clubs } 

public enum CardSuit { TheRedOne, TheBlackOne, TheOtherRedOne, TheOtherBlackOne } 

Bien sûr, le premier est beaucoup plus lisible pour les développeurs que le second. Cependant, un compilateur ne se soucie pas du signifiant des noms enum. Il importe seulement que la valeur appropriée soit utilisée uniformément.

C'est le même principe que les noms de variables. Bien sûr, nous devrions prendre soin de rendre les noms de variables lisibles par les développeurs; il n'y a pas raisons techniques raison (c'est-à-dire à la fonctionnalité de l'application) pourquoi nous devrions utiliser int myDescriptiveInteger sur int x.
Nous choisissons seulement un nom descriptif à des fins de lisibilité pour les humains qui maintiennent le code.


Il y a une seule exception: Si vous appelez .ToString() sur un ENUM, afin d'avoir une représentation de chaîne du champ que vous utilisez.

Note: Bien que cela soit techniquement possible et déjà fait par d'autres; Je me demande si c'est vraiment ce que vous devriez faire ici. Vous attribuez déjà des valeurs int explicites aux valeurs enum. Ces valeurs int sont beaucoup plus faciles pour enregistrer/charger une énumération au lieu d'essayer de travailler avec son équivalent de chaîne. Alors que les deux sont techniquement possibles, l'utilisation de l'int est bien meilleure en raison d'une plus petite empreinte et d'un manque du problème de nommage que vous essayez à tort de corriger ici.

Votre question ne précise pas si c'est le cas pour vous. Peut-être que c'est fait quelque part dans votre application, peut-être que ce n'est pas le cas. Je ne peux pas le savoir sans que tu me le dises.

Si elle ne se fait pas, votre problème est fonctionnellement hors de propos. Le nom n'a pas d'importance, sauf pour des raisons de lisibilité, et je suis tout à fait convaincu que vos développeurs ne cesseront pas soudain de comprendre l'intention du code, car il manque un tiret.

Si c'est fait, alors vous avez déjà fourni la réponse à votre problème. Au lieu d'appeler .ToString() sur l'énumération; Au lieu de cela, vous devez utiliser la valeur de [Display(Name="FirstElement")] comme "nom de chaîne" correct pour votre enum.

public static string GetName(this myEnum enumValue) 
{ 
    return enumValue.GetType() 
        .GetMember(enumValue.ToString()) 
        .GetCustomAttribute<DisplayAttribute>() 
        .GetName(); 
} 

Et vous pouvez modifier le code suivant:

myEnumValue.ToString(); 

le code suivant, qui utilise correctement la valeur de l'attribut au lieu du nom du champ ENUM:

myEnumValue.GetName(); 

Dans les deux cas, la réponse de base reste la même: Vous n'avez pas besoin de vous soucier du nom spécifique de vos champs enum car il est fonctionnellement non pertinent.


Modifier Si vous voulez que votre valeur ENUM à affichés différemment dans la zone de liste déroulante que vous voulez qu'il soit lorsque vous enregistrez la valeur, utilisez alors un second attribut de faire la différence entre les deux. Mais le principe est toujours le même: ne vous basez pas sur les noms de champs que n'utilise une énumération.

Et je tiens à souligner à nouveau que vous devriez utiliser les valeurs entières de votre énumération. Je ne vois pas pourquoi vous attribueriez explicitement des valeurs int à votre énumération et refuseriez ensuite de les utiliser.

+0

Je ne cherchais pas nécessairement à utiliser les noms de champs, c'est pourquoi j'ai essayé d'utiliser l'attribut Value, et pourquoi le titre indique une valeur personnalisée. Une méthode d'extension semble en effet la meilleure chose dans mon cas, celle qui utilise un attribut [Value], car je veux que [Display] reste séparé, car il a une signification différente. –