Essayer de mettre mon projet à jour vers MVC3, quelque chose que je ne trouve pas:
J'ai un type de données simple d'ENUMS:
public enum States()
{
AL,AK,AZ,...WY
}
Ce que je veux utiliser en tant que DropDown/SelectList dans ma vue d'un modèle contenant ce type de données:
public class FormModel()
{
public States State {get; set;}
}
Plutôt simple: quand je vais utiliser la vue auto-générer pour cette classe partielle, il ignore ce type.
J'ai besoin d'une simple liste de sélection qui définit la valeur de l'énum en tant qu'élément sélectionné lorsque je clique sur submit et que je le traite via ma méthode AJAX - JSON POST Méthode.
Et que la vue (???!):
<div class="editor-field">
@Html.DropDownListFor(model => model.State, model => model.States)
</div>
merci à l'avance pour les conseils!
Je viens de faire un pour mon propre projet. Le code ci-dessous fait partie de ma classe d'assistance, j'espère que j'ai toutes les méthodes nécessaires. Écrivez un commentaire si cela ne fonctionne pas et je vérifierai à nouveau.
public static class SelectExtensions
{
public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
string name = GetInputName(methodCallExpression);
return name.Substring(expression.Parameters[0].Name.Length + 1);
}
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}
private static string GetInputName(MethodCallExpression expression)
{
// p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw...
MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
if (methodCallExpression != null)
{
return GetInputName(methodCallExpression);
}
return expression.Object.ToString();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
string inputName = GetInputName(expression);
var value = htmlHelper.ViewData.Model == null
? default(TProperty)
: expression.Compile()(htmlHelper.ViewData.Model);
return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()));
}
public static SelectList ToSelectList(Type enumType, string selectedItem)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (var item in Enum.GetValues(enumType))
{
FieldInfo fi = enumType.GetField(item.ToString());
var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description;
var listItem = new SelectListItem
{
Value = ((int)item).ToString(),
Text = title,
Selected = selectedItem == ((int)item).ToString()
};
items.Add(listItem);
}
return new SelectList(items, "Value", "Text", selectedItem);
}
}
Utilisez-le comme:
Html.EnumDropDownListFor(m => m.YourEnum);
Mettre à jour
J'ai créé des helpers HTML alternatifs. Tout ce que vous avez à faire pour les utiliser est de changer votre page de base dans views\web.config
.
Avec eux, vous pouvez simplement faire:
@Html2.DropDownFor(m => m.YourEnum);
@Html2.CheckboxesFor(m => m.YourEnum);
@Html2.RadioButtonsFor(m => m.YourEnum);
Plus d'infos ici: http://blog.gauffin.org/2011/10/first-draft-of-my-alternative-html-helpers/
J'ai trouvé une solution plus simple pour cela ici: http://coding-in.net/asp-net-mvc-3-method-extension/
using System;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace EnumHtmlHelper.Helper
{
public static class EnumDropDownList
{
public static HtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement)
{
var typeOfProperty = modelExpression.ReturnType;
if(!typeOfProperty.IsEnum)
throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty));
var enumValues = new SelectList(Enum.GetValues(typeOfProperty));
return htmlHelper.DropDownListFor(modelExpression, enumValues, firstElement);
} } }
Une ligne de rasoir le fera:
@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States))))
Vous pouvez également trouver du code pour le faire avec une méthode d'extension dans l'article lié.
A partir de ASP.NET MVC 5.1 (RC1) , EnumDropDownListFor
est inclus par défaut en tant que méthode d'extension de HtmlHelper
.
Si vous voulez quelque chose de très simple, il existe un autre moyen, en fonction de la manière dont vous stockez l'état dans la base de données.
Si vous aviez une entité comme celle-ci:
public class Address
{
//other address fields
//this is what the state gets stored as in the db
public byte StateCode { get; set; }
//this maps our db field to an enum
public States State
{
get
{
return (States)StateCode;
}
set
{
StateCode = (byte)value;
}
}
}
Générer le menu déroulant serait aussi simple que cela:
@Html.DropDownListFor(x => x.StateCode,
from State state in Enum.GetValues(typeof(States))
select new SelectListItem() { Text = state.ToString(), Value = ((int)state).ToString() }
);
LINQ n'est-il pas beau?
J'ai pu faire cela dans un one-liner.
@Html.DropDownListFor(m=>m.YourModelProperty,new SelectList(Enum.GetValues(typeof(YourEnumType))))
Sur la base de la réponse acceptée de @jgauffin, j'ai créé ma propre version de EnumDropDownListFor
, qui traite du problème de la sélection d'éléments.
Le problème est détaillé dans autre SO répondez ici :, et découle fondamentalement d'une incompréhension du comportement des différentes surcharges de DropDownList
.
Mon code complet (qui inclut les surcharges pour htmlAttributes
etc est le suivant:
public static class EnumDropDownListForHelper
{
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, null, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, null, htmlAttributes);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IDictionary<string, object> htmlAttributes
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, null, htmlAttributes);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string optionLabel
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, optionLabel, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string optionLabel,
IDictionary<string,object> htmlAttributes
) where TModel : class
{
string inputName = GetInputName(expression);
return htmlHelper.DropDownList(
inputName, ToSelectList(typeof(TProperty)),
optionLabel, htmlAttributes);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string optionLabel,
object htmlAttributes
) where TModel : class
{
string inputName = GetInputName(expression);
return htmlHelper.DropDownList(
inputName, ToSelectList(typeof(TProperty)),
optionLabel, htmlAttributes);
}
private static string GetInputName<TModel, TProperty>(
Expression<Func<TModel, TProperty>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression methodCallExpression
= (MethodCallExpression)expression.Body;
string name = GetInputName(methodCallExpression);
return name.Substring(expression.Parameters[0].Name.Length + 1);
}
return expression.Body.ToString()
.Substring(expression.Parameters[0].Name.Length + 1);
}
private static string GetInputName(MethodCallExpression expression)
{
// p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw...
MethodCallExpression methodCallExpression
= expression.Object as MethodCallExpression;
if (methodCallExpression != null)
{
return GetInputName(methodCallExpression);
}
return expression.Object.ToString();
}
private static SelectList ToSelectList(Type enumType)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (var item in Enum.GetValues(enumType))
{
FieldInfo fi = enumType.GetField(item.ToString());
var attribute = fi.GetCustomAttributes(
typeof(DescriptionAttribute), true)
.FirstOrDefault();
var title = attribute == null ? item.ToString()
: ((DescriptionAttribute)attribute).Description;
var listItem = new SelectListItem
{
Value = item.ToString(),
Text = title,
};
items.Add(listItem);
}
return new SelectList(items, "Value", "Text");
}
}
J'ai écrit ceci sur mon blog ici .
J'ai apporté la modification suivante à la méthode SelectList pour qu'elle fonctionne un peu mieux pour moi. Peut-être que ce sera utile pour les autres.
public static SelectList ToSelectList<T>(T selectedItem)
{
if (!typeof(T).IsEnum) throw new InvalidEnumArgumentException("The specified type is not an enum");
var selectedItemName = Enum.GetName(typeof (T), selectedItem);
var items = new List<SelectListItem>();
foreach (var item in Enum.GetValues(typeof(T)))
{
var fi = typeof(T).GetField(item.ToString());
var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
var enumName = Enum.GetName(typeof (T), item);
var title = attribute == null ? enumName : ((DescriptionAttribute)attribute).Description;
var listItem = new SelectListItem
{
Value = enumName,
Text = title,
Selected = selectedItemName == enumName
};
items.Add(listItem);
}
return new SelectList(items, "Value", "Text");
}
public enum EnumStates
{
AL = 0,
AK = 1,
AZ = 2,
WY = 3
}
@Html.DropDownListFor(model => model.State, (from EnumStates e in Enum.GetValues(typeof(EnumStates))
select new SelectListItem { Value = ((int)e).ToString(), Text = e.ToString() }), "select", new { @style = "" })
@Html.ValidationMessageFor(model => model.State) //With select
//Or
@Html.DropDownListFor(model => model.State, (from EnumStates e in Enum.GetValues(typeof(EnumStates))
select new SelectListItem { Value = ((int)e).ToString(), Text = e.ToString() }), null, new { @style = "" })
@Html.ValidationMessageFor(model => model.State) //With out select
Cela serait utile pour sélectionner une valeur int de enum: Ici SpecType
est un champ int
... et enmSpecType
est un enum
.
@Html.DropDownList(
"SpecType",
YourNameSpace.SelectExtensions.ToSelectList(typeof(NREticaret.Core.Enums.enmSpecType),
Model.SpecType.ToString()), "Tip Seçiniz", new
{
gtbfieldid = "33",
@class = "small"
})
Identique à celle de Mike (qui est enterrée entre de longues réponses)
model.truckimagelocation est une propriété d'instance de classe du type d'énumération TruckImageLocation.
@Html.DropDownListFor(model=>model.truckimagelocation,Enum.GetNames(typeof(TruckImageLocation)).ToArray().Select(f=> new SelectListItem() {Text = f, Value = f, Selected = false}))
vous pouvez utiliser enum dans votre modèle
ton Enum
public enum States()
{
AL,AK,AZ,...WY
}
faire un modèle
public class enumclass
{
public States statesprop {get; set;}
}
en vue
@Html.Dropdownlistfor(a=>a.statesprop)
C'est le code le plus générique qui sera utilisé pour tous les Enums.
public static class UtilitiesClass
{
public static SelectList GetEnumType(Type enumType)
{
var value = from e in Enum.GetNames(enumType)
select new
{
ID = Convert.ToInt32(Enum.Parse(enumType, e, true)),
Name = e
};
return new SelectList(value, "ID", "Name");
}
}
Méthode d'action
ViewBag.Enum= UtilitiesClass.GetEnumType(typeof (YourEnumType));
View.cshtml
@Html.DropDownList("Type", (IEnumerable<SelectListItem>)ViewBag.Enum, new { @class = "form-control"})
La réponse la plus simple dans MVC5 est Define Enum:
public enum ReorderLevels {
zero = 0,
five = 5,
ten = 10,
fifteen = 15,
twenty = 20,
twenty_five = 25,
thirty = 30
}
Bind In View:
<div class="form-group">
<label>Reorder Level</label>
@Html.EnumDropDownListFor(m => m.ReorderLevel, "Choose Me", new { @class = "form-control" })
</div>