私はHtml.DropDownList
拡張メソッドを使用しようとしていますが、列挙でそれを使用する方法を理解することはできません。
私はこのような列挙があるとしましょう:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
Html.DropDownList
拡張メソッドを使用してこれらの値でドロップダウンを作成する方法を教えてください。
それとも、単純にforループを作成してHTML要素を手動で作成するのが最善の方法でしょうか。
@Html.EnumDropDownListFor(
x => x.YourEnumField,
"Select My Type",
new { @class = "form-control" })
@Html.DropDownList("MyType",
EnumHelper.GetSelectList(typeof(MyType)) ,
"Select My Type",
new { @class = "form-control" })
私はRuneの答えを拡張方法にまとめました。
namespace MyApp.Common
{
public static class MyExtensions{
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
}
}
これはあなたが書くことができます:
ViewData["taskStatus"] = task.Status.ToSelectList();
using MyApp.Common
著
私はこれについてパーティーに遅れていることを知っています、しかしあなたはこの変種がドロップダウンで列挙定数よりむしろ説明的な文字列を使うことを可能にするのであなたがこの変種が役に立つと思うかもしれないと思いました。これを行うには、各列挙型エントリを[System.ComponentModel.Description]属性で装飾します。
例えば:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
これが私のコードです:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Reflection;
using System.ComponentModel;
using System.Linq.Expressions;
...
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
public static string GetEnumDescription<TEnum>(TEnum 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();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return EnumDropDownListFor(htmlHelper, expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = from value in values
select new SelectListItem
{
Text = GetEnumDescription(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
};
// If the enum is nullable, add an 'empty' item to the collection
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
あなたはそれからあなたの見解でこれをすることができます:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
これがお役に立てば幸いです。
**編集2014-JAN-23:マイクロソフトはMVC 5.1をリリースしたばかりで、現在はEnumDropDownListFor機能を備えています。残念ながら、それは[Description]属性を尊重しているようには見えないので、上のコードはまだ立っています。 Enumセクションの MicrosoftのMVC 5.1リリースノート。
更新:これは 表示 属性[Display(Name = "Sample")]
をサポートしていますので、それを使うことができます。
[更新 - これに気づいた、そしてコードはここでコードの拡張版のように見える: https://blogs.msdn.Microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating- - ドロップダウンリスト - 列挙型ヘルパー/ 、いくつかの追加。もしそうなら、帰属は公平に見えるでしょう;-)]
ASP.NET MVC 5.1では、EnumDropDownListFor()
ヘルパーを追加したため、カスタム拡張機能は不要です。
モデル:
public enum MyEnum
{
[Display(Name = "First Value - desc..")]
FirstValue,
[Display(Name = "Second Value - desc...")]
SecondValue
}
表示:
@Html.EnumDropDownListFor(model => model.MyEnum)
タグヘルパーの使用(ASP.NET MVC 6):
<select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()">
私は同じ問題にぶつかり、この問題を見つけ、Ashが提供した解決策は私が探していたものではないと考えました。 HTMLを自分で作成しなければならないということは、組み込みのHtml.DropDownList()
関数に比べて柔軟性が低いことを意味します。
C#3などが判明すれば、これは非常に簡単です。 enum
というTaskStatus
があります。
var statuses = from TaskStatus s in Enum.GetValues(typeof(TaskStatus))
select new { ID = s, Name = s.ToString() };
ViewData["taskStatus"] = new SelectList(statuses, "ID", "Name", task.Status);
これは、ビューで慣れ親しんだように使える古き良きSelectList
を作成します。
<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>
匿名型とLINQにより、これははるかにエレガントな私見になります。悪意はない、アッシュ。 :)
これがより良いカプセル化ソリューションです。
https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5
ここにあなたのモデルがいるとします。
使用例:
生成されたUI:
そして生成されたHTML
ヘルパー拡張ソースコードのスナップショット:
あなたは私が提供したリンクからサンプルプロジェクトをダウンロードすることができます。
編集:これはコードです:
public static class EnumEditorHtmlHelper
{
/// <summary>
/// Creates the DropDown List (HTML Select Element) from LINQ
/// Expression where the expression returns an Enum type.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TProperty">The type of the property.</typeparam>
/// <param name="htmlHelper">The HTML helper.</param>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression)
where TModel : class
{
TProperty value = htmlHelper.ViewData.Model == null
? default(TProperty)
: expression.Compile()(htmlHelper.ViewData.Model);
string selected = value == null ? String.Empty : value.ToString();
return htmlHelper.DropDownListFor(expression, createSelectList(expression.ReturnType, selected));
}
/// <summary>
/// Creates the select list.
/// </summary>
/// <param name="enumType">Type of the enum.</param>
/// <param name="selectedItem">The selected item.</param>
/// <returns></returns>
private static IEnumerable<SelectListItem> createSelectList(Type enumType, string selectedItem)
{
return (from object item in Enum.GetValues(enumType)
let fi = enumType.GetField(item.ToString())
let attribute = fi.GetCustomAttributes(typeof (DescriptionAttribute), true).FirstOrDefault()
let title = attribute == null ? item.ToString() : ((DescriptionAttribute) attribute).Description
select new SelectListItem
{
Value = item.ToString(),
Text = title,
Selected = selectedItem == item.ToString()
}).ToList();
}
}
Html.DropDownListForにはIEnumerableしか必要ありません。そのため、Priseの解決策に代わるものは次のとおりです。これはあなたが単に書くことを可能にするでしょう:
@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())
[SelectedItemTypeは、ItemTypes型のモデルのフィールドで、モデルはnull以外の値です]
また、typeof(T)ではなくenumValue.GetType()を使用できるため、拡張メソッドを一般化する必要はありません。
編集:ここでも同様にサイモンのソリューションを統合し、ToDescription拡張メソッドが含まれています。
public static class EnumExtensions
{
public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue)
{
return from Enum e in Enum.GetValues(enumValue.GetType())
select new SelectListItem
{
Selected = e.Equals(enumValue),
Text = e.ToDescription(),
Value = e.ToString()
};
}
public static string ToDescription(this Enum value)
{
var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
}
あなたがシンプルで簡単を探しているのであれば拡張機能なしで..これは私がやったことです
<%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%>
xXXXX.Sites.YYYY.Models.Stateは列挙型です。
おそらくヘルパー機能を使うほうが良いでしょうが、時間が短いときにはこれで作業が完了します。
選択リスト項目のvalue属性を文字列値ではなく列挙型の整数値にマップする場合は、PrizeとRuneの回答を拡張して、次のコードを使用します。
public static SelectList ToSelectList<T, TU>(T enumObj)
where T : struct
where TU : struct
{
if(!typeof(T).IsEnum) throw new ArgumentException("Enum is required.", "enumObj");
var values = from T e in Enum.GetValues(typeof(T))
select new {
Value = (TU)Convert.ChangeType(e, typeof(TU)),
Text = e.ToString()
};
return new SelectList(values, "Value", "Text", enumObj);
}
各Enumeration値をTEnumオブジェクトとして扱う代わりに、それをオブジェクトとして扱い、それを整数にキャストして、ボックス化されていない値を取得することができます。
注: Iこの拡張が利用できる型を構造体(Enumの基本型)のみに制限するためのジェネリック型制約、および渡された構造体が実際にEnumであることを保証する実行時型検証も追加しました。 。
更新10/23/12: 基礎となる型のジェネリック型パラメータを追加し、.NET 4+に影響するコンパイル以外の問題を修正。
このために私が見つけた最良の解決策は、 このブログ with Simon Goldstone's answer を組み合わせることでした。
これにより、モデル内でenumを使用できます。基本的には、列挙型と同様に整数型プロパティを使用し、整数型プロパティをエミュレートするという考えです。
次に、[System.ComponentModel.Description]属性を使用してモデルに表示テキストで注釈を付け、ビューで "EnumDropDownListFor"拡張子を使用します。
これにより、ビューとモデルの両方が非常に読みやすく保守しやすくなります。
モデル:
public enum YesPartialNoEnum
{
[Description("Yes")]
Yes,
[Description("Still undecided")]
Partial,
[Description("No")]
No
}
//........
[Display(Name = "The label for my dropdown list")]
public virtual Nullable<YesPartialNoEnum> CuriousQuestion{ get; set; }
public virtual Nullable<int> CuriousQuestionId
{
get { return (Nullable<int>)CuriousQuestion; }
set { CuriousQuestion = (Nullable<YesPartialNoEnum>)value; }
}
見る:
@using MyProject.Extensions
{
//...
@Html.EnumDropDownListFor(model => model.CuriousQuestion)
//...
}
拡張子( Simon Goldstoneの回答 から直接、完全性のためここに含まれています):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel;
using System.Reflection;
using System.Linq.Expressions;
using System.Web.Mvc.Html;
namespace MyProject.Extensions
{
//Extension methods must be defined in a static class
public static class MvcExtensions
{
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if (underlyingType != null)
{
realModelType = underlyingType;
}
return realModelType;
}
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
public static string GetEnumDescription<TEnum>(TEnum 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();
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return EnumDropDownListFor(htmlHelper, expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = from value in values
select new SelectListItem
{
Text = GetEnumDescription(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
};
// If the enum is nullable, add an 'empty' item to the collection
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
}
}
Priseの拡張方法を使用してテキストの代わりに番号を取得する問題を解決するため。
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
, Name = e.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
これを成し遂げるための超簡単な方法 - やり過ぎるようなすべての拡張機能なしでこれはこれです:
あなたのenum:
public enum SelectedLevel
{
Level1,
Level2,
Level3,
Level4
}
あなたのコントローラの内側でリストにEnumをバインドします:
List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();
その後、それをViewBagに投げ込みます。
ViewBag.RequiredLevel = new SelectList(myLevels);
最後にそれを単にViewにバインドします。
@Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })
これは私が見つけたはるかに簡単な方法であり、拡張機能や狂気のものは不要です。
_ update _ :以下のAndrewsのコメントを参照。
Enum.GetValues
のようなものを使って見たいのですが。
@Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))
これはIDとしてEnumのint
の値を使うように変更されたRune&Prizeの回答です。
サンプルの列挙:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
延長方法:
public static SelectList ToSelectList<TEnum>(this TEnum enumObj)
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() };
return new SelectList(values, "Id", "Name", (int)Enum.Parse(typeof(TEnum), enumObj.ToString()));
}
使用例
<%= Html.DropDownList("MyEnumList", ItemTypes.Game.ToSelectList()) %>
Extensionメソッドを含む名前空間をインポートすることを忘れないでください
<%@ Import Namespace="MyNamespace.LocationOfExtensionMethod" %>
生成されたHTMLのサンプル:
<select id="MyEnumList" name="MyEnumList">
<option value="1">Movie</option>
<option selected="selected" value="2">Game</option>
<option value="3">Book </option>
</select>
ToSelectList
を呼び出すために使用する項目は選択された項目です。
これはRazor用のバージョンです。
@{
var itemTypesList = new List<SelectListItem>();
itemTypesList.AddRange(Enum.GetValues(typeof(ItemTypes)).Cast<ItemTypes>().Select(
(item, index) => new SelectListItem
{
Text = item.ToString(),
Value = (index).ToString(),
Selected = Model.ItemTypeId == index
}).ToList());
}
@Html.DropDownList("ItemTypeId", itemTypesList)
現在、この機能は、MVC 5.1から@Html.EnumDropDownListFor()
までの間、すぐにサポートされます。
次のリンクを確認してください。
https://docs.Microsoft.com/ja-jp/aspnet/mvc/overview/releases/mvc51-release-notes#Enum
上記の投票によると、それほど需要がある機能などを実装するのにMicrosoftが5年かかったのは本当に残念です!
私は本当にパーティーに遅刻しました、しかし、それが価値があるもののために、私は非常に簡単な変換を可能にするEnumHelper
クラスを作成するというまさしくその主題についてブログを書きました。
http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23
あなたのコントローラーで:
//If you don't have an enum value use the type
ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>();
//If you do have an enum value use the value (the value will be marked as selected)
ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue);
あなたの見解では:
@Html.DropDownList("DropDownList")
@* OR *@
@Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)
ヘルパークラス:
public static class EnumHelper
{
// Get the value of the description attribute if the
// enum has one, otherwise use the value.
public static string GetDescription<TEnum>(this TEnum value)
{
var fi = value.GetType().GetField(value.ToString());
if (fi != null)
{
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return attributes[0].Description;
}
}
return value.ToString();
}
/// <summary>
/// Build a select list for an enum
/// </summary>
public static SelectList SelectListFor<T>() where T : struct
{
Type t = typeof(T);
return !t.IsEnum ? null
: new SelectList(BuildSelectListItems(t), "Value", "Text");
}
/// <summary>
/// Build a select list for an enum with a particular value selected
/// </summary>
public static SelectList SelectListFor<T>(T selected) where T : struct
{
Type t = typeof(T);
return !t.IsEnum ? null
: new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString());
}
private static IEnumerable<SelectListItem> BuildSelectListItems(Type t)
{
return Enum.GetValues(t)
.Cast<Enum>()
.Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() });
}
}
Simonの答えに基づいて、同様のアプローチはEnum自身の中のdescription属性の代わりにリソースファイルから表示するためにEnum値を得ることです。サイトを複数の言語でレンダリングする必要がある場合や、Enum用の特定のリソースファイルがある場合は、さらに一歩進んでEnum値だけをEnumに格納し、それらを拡張から次のように参照して参照できます。 [EnumName] _ [EnumValue]のような規則 - 最終的には入力が少なくなります。
拡張子は次のようになります。
public static IHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, TEnum>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType;
var enumValues = Enum.GetValues(enumType).Cast<object>();
var items = from enumValue in enumValues
select new SelectListItem
{
Text = GetResourceValueForEnumValue(enumValue),
Value = ((int)enumValue).ToString(),
Selected = enumValue.Equals(metadata.Model)
};
return html.DropDownListFor(expression, items, string.Empty, null);
}
private static string GetResourceValueForEnumValue<TEnum>(TEnum enumValue)
{
var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue);
return Enums.ResourceManager.GetString(key) ?? enumValue.ToString();
}
ItemTypes_Movie:Filmのように見えるEnums.Resxファイル内のリソース
私がやりたいもう一つのことは、拡張メソッドを直接呼び出すのではなく、@ Html.EditorFor(x => x.MyProperty)を使って呼び出すか、理想的にはフォーム全体を1つの形式で作成することです。 Html.EditorForModel()これを行うには、文字列テンプレートを次のように変更します。
@using MVCProject.Extensions
@{
var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType;
@(typeof (Enum).IsAssignableFrom(type) ? Html.EnumDropDownListFor(x => x) : Html.TextBoxFor(x => x))
}
これに興味があるなら、私のブログにもっと詳細な答えをここに載せておきます。
私はこれに非常に遅れています、しかしあなたが 制約のないMelody NuGetパッケージ(Jon Skeetからの素晴らしい、小さいライブラリー)を追加して満足であれば私はちょうど1行のコードでこれをする本当にクールな方法を見つけました).
この解決策は、以下の点で優れています。
だから、これはこれを機能させるための手順です:
モデルに次のようにプロパティを追加します。
//Replace "YourEnum" with the type of your enum
public IEnumerable<SelectListItem> AllItems
{
get
{
return Enums.GetValues<YourEnum>().Select(enumValue => new SelectListItem { Value = enumValue.ToString(), Text = enumValue.GetDescription() });
}
}
SelectListItemのリストがモデルに公開されたので、このプロパティをソースとして使用して@ Html.DropDownListまたは@ Html.DropDownListForを使用できます。
.NET Coreでは、これを使うことができます。
@Html.DropDownListFor(x => x.Foo, Html.GetEnumSelectList<MyEnum>())
Griffin.MvcContribで私のカスタムHtmlHelpersを使うこともできます。次のコード
@Html2.CheckBoxesFor(model => model.InputType) <br />
@Html2.RadioButtonsFor(model => model.InputType) <br />
@Html2.DropdownFor(model => model.InputType) <br />
生成します。
ローカライゼーションサポートを追加したい場合は、s.toString()メソッドを次のように変更するだけです。
ResourceManager rManager = new ResourceManager(typeof(Resources));
var dayTypes = from OperatorCalendarDay.OperatorDayType s in Enum.GetValues(typeof(OperatorCalendarDay.OperatorDayType))
select new { ID = s, Name = rManager.GetString(s.ToString()) };
ここではtypeof(Resources)がロードしたいリソースであり、ローカライズされたStringを取得します。列挙子に複数の単語を含む値がある場合にも役立ちます。
これは私のバージョンのヘルパーメソッドです。私はこれを使う:
var values = from int e in Enum.GetValues(typeof(TEnum))
select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
その代わりに:
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
, Name = e.ToString() };
ここにあります:
public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct
{
if (!typeof(TEnum).IsEnum)
{
throw new ArgumentException("self must be enum", "self");
}
Type t = typeof(TEnum);
var values = from int e in Enum.GetValues(typeof(TEnum))
select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
return new SelectList(values, "ID", "Name", self);
}
答えが見つかりました ここ 。しかし、私のenumのいくつかは[Description(...)]
属性を持っているので、それをサポートするようにコードを修正しました:
enum Abc
{
[Description("Cba")]
Abc,
Def
}
public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string name, TEnum selectedValue)
{
IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum))
.Cast<TEnum>();
List<SelectListItem> items = new List<SelectListItem>();
foreach (var value in values)
{
string text = value.ToString();
var member = typeof(TEnum).GetMember(value.ToString());
if (member.Count() > 0)
{
var customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (customAttributes.Count() > 0)
{
text = ((DescriptionAttribute)customAttributes[0]).Description;
}
}
items.Add(new SelectListItem
{
Text = text,
Value = value.ToString(),
Selected = (value.Equals(selectedValue))
});
}
return htmlHelper.DropDownList(
name,
items
);
}
それが役立つことを願っています。
この拡張方法に対するもう一つの修正 - 現在のバージョンはenumの現在の値を選択しませんでした。最後の行を修正しました。
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()
};
return new SelectList(values, "ID", "Name", ((int)Enum.Parse(typeof(TEnum), enumObj.ToString())).ToString());
}
ユーザーがcontroller
またはLinq
式で何もする必要がない場合は、別の方法でこの質問に答えます。こちらです...
私はENUM
を持っています
public enum AccessLevelEnum
{
/// <summary>
/// The user cannot access
/// </summary>
[EnumMember, Description("No Access")]
NoAccess = 0x0,
/// <summary>
/// The user can read the entire record in question
/// </summary>
[EnumMember, Description("Read Only")]
ReadOnly = 0x01,
/// <summary>
/// The user can read or write
/// </summary>
[EnumMember, Description("Read / Modify")]
ReadModify = 0x02,
/// <summary>
/// User can create new records, modify and read existing ones
/// </summary>
[EnumMember, Description("Create / Read / Modify")]
CreateReadModify = 0x04,
/// <summary>
/// User can read, write, or delete
/// </summary>
[EnumMember, Description("Create / Read / Modify / Delete")]
CreateReadModifyDelete = 0x08,
/*/// <summary>
/// User can read, write, or delete
/// </summary>
[EnumMember, Description("Create / Read / Modify / Delete / Verify / Edit Capture Value")]
CreateReadModifyDeleteVerify = 0x16*/
}
今は、このdropdown
を使ってenum
を作成することはできません。
@Html.DropDownList("accessLevel",new SelectList(AccessLevelEnum.GetValues(typeof(AccessLevelEnum))),new { @class = "form-control" })
OR
@Html.DropDownListFor(m=>m.accessLevel,new SelectList(AccessLevelEnum.GetValues(typeof(AccessLevelEnum))),new { @class = "form-control" })
インデックスを選択したい場合はこれを試してください
@Html.DropDownListFor(m=>m.accessLevel,new SelectList(AccessLevelEnum.GetValues(typeof(AccessLevelEnum)) , AccessLevelEnum.NoAccess ),new { @class = "form-control" })
ここでは、ドロップダウンをデフォルトで選択するための追加パラメータとしてAccessLevelEnum.NoAccess
を使用しました。
@Html.DropDownListFor(model => model.MaritalStatus, new List<SelectListItem>
{
new SelectListItem { Text = "----Select----", Value = "-1" },
new SelectListItem { Text = "Marrid", Value = "M" },
new SelectListItem { Text = "Single", Value = "S" }
})
@Html.DropdownListFor(model=model->Gender,new List<SelectListItem>
{
new ListItem{Text="Male",Value="Male"},
new ListItem{Text="Female",Value="Female"},
new ListItem{Text="--- Select -----",Value="-----Select ----"}
}
)
ここで本質的に受け入れられている答えを実行するための拡張メソッドを作成しました。要旨の後半では、特にEnumについて説明します。
ローカライズに最適なカスタムラベルを配置できるMartin Faartoftのバリエーションです。
public static class EnumHtmlHelper
{
public static SelectList ToSelectList<TEnum>(this TEnum enumObj, Dictionary<int, string> customLabels)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { Id = e, Name = customLabels.First(x => x.Key == Convert.ToInt32(e)).Value.ToString() };
return new SelectList(values, "Id", "Name", enumObj);
}
}
視野内で使用する:
@Html.DropDownListFor(m => m.Category, Model.Category.ToSelectList(new Dictionary<int, string>() {
{ 1, ContactResStrings.FeedbackCategory },
{ 2, ContactResStrings.ComplainCategory },
{ 3, ContactResStrings.CommentCategory },
{ 4, ContactResStrings.OtherCategory }
}), new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Category)
//// ViewModel
public class RegisterViewModel
{
public RegisterViewModel()
{
ActionsList = new List<SelectListItem>();
}
public IEnumerable<SelectListItem> ActionsList { get; set; }
public string StudentGrade { get; set; }
}
//// Enum Class
public enum GradeTypes
{
A,
B,
C,
D,
E,
F,
G,
H
}
////Controller action
public ActionResult Student()
{
RegisterViewModel vm = new RegisterViewModel();
IEnumerable<GradeTypes> actionTypes = Enum.GetValues(typeof(GradeTypes))
.Cast<GradeTypes>();
vm.ActionsList = from action in actionTypes
select new SelectListItem
{
Text = action.ToString(),
Value = action.ToString()
};
return View(vm);
}
////// View Action
<div class="form-group">
<label class="col-lg-2 control-label" for="hobies">Student Grade:</label>
<div class="col-lg-10">
@Html.DropDownListFor(model => model.StudentGrade, Model.ActionsList, new { @class = "form-control" })
</div>
MVC4では、私はこれが好きです
@Html.DropDownList("RefType", new SelectList(Enum.GetValues(typeof(WebAPIApp.Models.RefType))), " Select", new { @class = "form-control" })
public enum RefType
{
Web = 3,
API = 4,
Security = 5,
FE = 6
}
public class Reference
{
public int Id { get; set; }
public RefType RefType { get; set; }
}
私は以下の作業を行い、正常に動作しています。
@model MyModel.cs
@Html.EnumDropDownListFor(m=>m.MyItemType )
public ItemTypes MyItemType { get; set; }
@Simon Goldstone:あなたの解決策をありがとう、それは私の場合には完全に適用することができます。唯一の問題は私がそれをVBに翻訳しなければならなかったということです。しかし今では完了し、他の人々の時間を節約するために(彼らがそれを必要とする場合)私はそれをここに置きます:
Imports System.Runtime.CompilerServices
Imports System.ComponentModel
Imports System.Linq.Expressions
Public Module HtmlHelpers
Private Function GetNonNullableModelType(modelMetadata As ModelMetadata) As Type
Dim realModelType = modelMetadata.ModelType
Dim underlyingType = Nullable.GetUnderlyingType(realModelType)
If Not underlyingType Is Nothing Then
realModelType = underlyingType
End If
Return realModelType
End Function
Private ReadOnly SingleEmptyItem() As SelectListItem = {New SelectListItem() With {.Text = "", .Value = ""}}
Private Function GetEnumDescription(Of TEnum)(value As TEnum) As String
Dim fi = value.GetType().GetField(value.ToString())
Dim attributes = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
If Not attributes Is Nothing AndAlso attributes.Length > 0 Then
Return attributes(0).Description
Else
Return value.ToString()
End If
End Function
<Extension()>
Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum))) As MvcHtmlString
Return EnumDropDownListFor(htmlHelper, expression, Nothing)
End Function
<Extension()>
Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum)), htmlAttributes As Object) As MvcHtmlString
Dim metaData As ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
Dim enumType As Type = GetNonNullableModelType(metaData)
Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(enumType).Cast(Of TEnum)()
Dim items As IEnumerable(Of SelectListItem) = From value In values
Select New SelectListItem With
{
.Text = GetEnumDescription(value),
.Value = value.ToString(),
.Selected = value.Equals(metaData.Model)
}
' If the enum is nullable, add an 'empty' item to the collection
If metaData.IsNullableValueType Then
items = SingleEmptyItem.Concat(items)
End If
Return htmlHelper.DropDownListFor(expression, items, htmlAttributes)
End Function
End Module
これを次のように使用します。
@Html.EnumDropDownListFor(Function(model) (model.EnumField))
1-あなたのENUMを作成する
public enum LicenseType
{
xxx = 1,
yyy = 2
}
2-あなたのサービスクラスを作成する
public class LicenseTypeEnumService
{
public static Dictionary<int, string> GetAll()
{
var licenseTypes = new Dictionary<int, string>();
licenseTypes.Add((int)LicenseType.xxx, "xxx");
licenseTypes.Add((int)LicenseType.yyy, "yyy");
return licenseTypes;
}
public static string GetById(int id)
{
var q = (from p in this.GetAll() where p.Key == id select p).Single();
return q.Value;
}
}
3-コントローラにViewBagを設定します
var licenseTypes = LicenseTypeEnumService.GetAll();
ViewBag.LicenseTypes = new SelectList(licenseTypes, "Key", "Value");
4- DropDownListをバインドします
@Html.DropDownList("LicenseType", (SelectList)ViewBag.LicenseTypes)