Imaginez que j'ai une énumération comme celle-ci (juste à titre d'exemple):
public enum Direction{
Horizontal = 0,
Vertical = 1,
Diagonal = 2
}
Comment puis-je écrire une routine pour obtenir ces valeurs dans un System.Web.Mvc.SelectList, étant donné que le contenu de l'énumération est susceptible de changer à l'avenir? Je veux obtenir chaque nom d'énumérations comme texte d'option et sa valeur comme texte de valeur, comme ceci:
<select>
<option value="0">Horizontal</option>
<option value="1">Vertical</option>
<option value="2">Diagonal</option>
</select>
C’est ce que je peux faire de mieux à ce jour:
public static SelectList GetDirectionSelectList()
{
Array values = Enum.GetValues(typeof(Direction));
List<ListItem> items = new List<ListItem>(values.Length);
foreach (var i in values)
{
items.Add(new ListItem
{
Text = Enum.GetName(typeof(Direction), i),
Value = i.ToString()
});
}
return new SelectList(items);
}
Toutefois, cela rend toujours le texte de l’option sous la forme 'System.Web.Mvc.ListItem'. Le débogage à travers cela me montre également que Enum.GetValues () renvoie "Horizontal, Vertical" etc. au lieu de 0, 1 comme je l'aurais prévu, ce qui me fait me demander quelle est la différence entre Enum.GetName () et Enum. GetValue ().
Pour obtenir la valeur d'une énumération, vous devez la convertir en son type sous-jacent:
Value = ((int)i).ToString();
Cela fait longtemps que je n'ai pas à faire cela, mais je pense que cela devrait fonctionner.
var directions = from Direction d in Enum.GetValues(typeof(Direction))
select new { ID = (int)d, Name = d.ToString() };
return new SelectList(directions , "ID", "Name", someSelectedValue);
Il existe une nouvelle fonctionnalité dans ASP.NET MVC 5.1 pour cela.
http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum
@Html.EnumDropDownListFor(model => model.Direction)
C'est ce que je viens de faire et personnellement je trouve ça sexy:
public static IEnumerable<SelectListItem> GetEnumSelectList<T>()
{
return (Enum.GetValues(typeof(T)).Cast<T>().Select(
enu => new SelectListItem() { Text = enu.ToString(), Value = enu.ToString() })).ToList();
}
Je vais éventuellement faire quelques traductions pour que Value = enu.ToString () appelle quelque chose quelque part.
Je voulais faire quelque chose de très similaire à la solution de Dann, mais j'avais besoin que Value soit un int et que le texte soit la représentation sous forme de chaîne de Enum. Voici ce que je suis venu avec:
public static IEnumerable<SelectListItem> GetEnumSelectList<T>()
{
return (Enum.GetValues(typeof(T)).Cast<int>().Select(e => new SelectListItem() { Text = Enum.GetName(typeof(T), e), Value = e.ToString() })).ToList();
}
return
Enum
.GetNames(typeof(ReceptionNumberType))
.Where(i => (ReceptionNumberType)(Enum.Parse(typeof(ReceptionNumberType), i.ToString())) < ReceptionNumberType.MCI)
.Select(i => new
{
description = i,
value = (Enum.Parse(typeof(ReceptionNumberType), i.ToString()))
});
Ou:
foreach (string item in Enum.GetNames(typeof(MyEnum)))
{
myDropDownList.Items.Add(new ListItem(item, ((int)((MyEnum)Enum.Parse(typeof(MyEnum), item))).ToString()));
}
Dans ASP.NET Core MVC, cette opération est effectuée avec les assistants tag .
<select asp-items="Html.GetEnumSelectList<Direction>()"></select>
peut-être pas une réponse exacte à la question, mais dans les scénarios CRUD, j’implémente généralement quelque chose comme:
private void PopulateViewdata4Selectlists(ImportJob job)
{
ViewData["Fetcher"] = from ImportFetcher d in Enum.GetValues(typeof(ImportFetcher))
select new SelectListItem
{
Value = ((int)d).ToString(),
Text = d.ToString(),
Selected = job.Fetcher == d
};
}
PopulateViewdata4Selectlists
est appelé avant View ("Create") et View ("Edit"), puis et dans la vue:
<%= Html.DropDownList("Fetcher") %>
et c'est tout..
public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");
var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() };
//var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() };
return new SelectList(values, "ID", "Name", enumObj);
}
public static SelectList ToSelectList<TEnum>(this TEnum enumObj, string selectedValue) where TEnum : struct
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");
var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() };
//var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.ToString() };
if (string.IsNullOrWhiteSpace(selectedValue))
{
return new SelectList(values, "ID", "Name", enumObj);
}
else
{
return new SelectList(values, "ID", "Name", selectedValue);
}
}
J'ai plus de classes et de méthodes pour diverses raisons:
Enum à la collection d'objets
public static class EnumHelper
{
public static List<ItemDto> EnumToCollection<T>()
{
return (Enum.GetValues(typeof(T)).Cast<int>().Select(
e => new ItemViewModel
{
IntKey = e,
Value = Enum.GetName(typeof(T), e)
})).ToList();
}
}
Création d'une liste de sélection dans le contrôleur
int selectedValue = 1; // resolved from anywhere
ViewBag.Currency = new SelectList(EnumHelper.EnumToCollection<Currency>(), "Key", "Value", selectedValue);
MyView.cshtml
@Html.DropDownListFor(x => x.Currency, null, htmlAttributes: new { @class = "form-control" })
J'avais beaucoup de listes de sélection enum et, après beaucoup de recherches et de tamisages, j'ai constaté que faire un assistant générique fonctionnait mieux pour moi. Il renvoie l'index ou le descripteur en tant que valeur Selectlist et la description en tant que texte Selectlist:
Enum:
public enum Your_Enum
{
[Description("Description 1")]
item_one,
[Description("Description 2")]
item_two
}
Assistant:
public static class Selectlists
{
public static SelectList EnumSelectlist<TEnum>(bool indexed = false) where TEnum : struct
{
return new SelectList(Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(item => new SelectListItem
{
Text = GetEnumDescription(item as Enum),
Value = indexed ? Convert.ToInt32(item).ToString() : item.ToString()
}).ToList(), "Value", "Text");
}
// NOTE: returns Descriptor if there is no Description
private static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
Utilisation: Définissez le paramètre sur 'true' pour les index comme valeur:
var descriptorsAsValue = Selectlists.EnumSelectlist<Your_Enum>();
var indicesAsValue = Selectlists.EnumSelectlist<Your_Enum>(true);