回答:
データは列挙型であるため、おそらくバインドしません。また、コンパイル時に変更されません(これらの愚かな瞬間がない限り)。
列挙型を反復するだけの方が良い:
Dim itemValues As Array = System.Enum.GetValues(GetType(Response))
Dim itemNames As Array = System.Enum.GetNames(GetType(Response))
For i As Integer = 0 To itemNames.Length - 1
Dim item As New ListItem(itemNames(i), itemValues(i))
dropdownlist.Items.Add(item)
Next
またはC#でも同じ
Array itemValues = System.Enum.GetValues(typeof(Response));
Array itemNames = System.Enum.GetNames(typeof(Response));
for (int i = 0; i <= itemNames.Length - 1 ; i++) {
ListItem item = new ListItem(itemNames[i], itemValues[i]);
dropdownlist.Items.Add(item);
}
Enumerationから(Enum値と名前のペア)Enumerationを取得するには、次のユーティリティクラスを使用します。次に、IDictionaryをバインド可能なコントロールにバインドします。IDictionary<int,string>
public static class Enumeration
{
public static IDictionary<int, string> GetAll<TEnum>() where TEnum: struct
{
var enumerationType = typeof (TEnum);
if (!enumerationType.IsEnum)
throw new ArgumentException("Enumeration type is expected.");
var dictionary = new Dictionary<int, string>();
foreach (int value in Enum.GetValues(enumerationType))
{
var name = Enum.GetName(enumerationType, value);
dictionary.Add(value, name);
}
return dictionary;
}
}
例:ユーティリティクラスを使用して列挙データをコントロールにバインドする
ddlResponse.DataSource = Enumeration.GetAll<Response>();
ddlResponse.DataTextField = "Value";
ddlResponse.DataValueField = "Key";
ddlResponse.DataBind();
私のバージョンは上記の圧縮形式です:
foreach (Response r in Enum.GetValues(typeof(Response)))
{
ListItem item = new ListItem(Enum.GetName(typeof(Response), r), r.ToString());
DropDownList1.Items.Add(item);
}
public enum Color
{
RED,
GREEN,
BLUE
}
すべての列挙型はSystem.Enumから派生します。ドロップダウンリストコントロールへのデータのバインド(および値の取得)に役立つ2つの静的メソッドがあります。これらはEnum.GetNamesとEnum.Parseです。GetNamesを使用すると、次のようにドロップダウンリストコントロールにバインドできます。
protected System.Web.UI.WebControls.DropDownList ddColor;
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
ddColor.DataSource = Enum.GetNames(typeof(Color));
ddColor.DataBind();
}
}
Enumの値を選択に戻す場合は、次のようにします。
private void ddColor_SelectedIndexChanged(object sender, System.EventArgs e)
{
Color selectedColor = (Color)Enum.Parse(typeof(Color),ddColor.SelectedValue
}
すべての投稿を読んだ後、ドロップダウンリストに列挙型の説明を表示し、編集モードで表示するときにドロップダウンのモデルから適切な値を選択することをサポートする包括的なソリューションを思い付きました:
列挙型:
using System.ComponentModel;
public enum CompanyType
{
[Description("")]
Null = 1,
[Description("Supplier")]
Supplier = 2,
[Description("Customer")]
Customer = 3
}
列挙型拡張クラス:
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
public static class EnumExtension
{
public static string ToDescription(this System.Enum value)
{
var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public static IEnumerable<SelectListItem> ToSelectList<T>(this System.Enum enumValue)
{
return
System.Enum.GetValues(enumValue.GetType()).Cast<T>()
.Select(
x =>
new SelectListItem
{
Text = ((System.Enum)(object) x).ToDescription(),
Value = x.ToString(),
Selected = (enumValue.Equals(x))
});
}
}
モデルクラス:
public class Company
{
public string CompanyName { get; set; }
public CompanyType Type { get; set; }
}
と表示:
@Html.DropDownListFor(m => m.Type,
@Model.Type.ToSelectList<CompanyType>())
モデルにバインドせずにドロップダウンを使用している場合は、代わりにこれを使用できます。
@Html.DropDownList("type",
Enum.GetValues(typeof(CompanyType)).Cast<CompanyType>()
.Select(x => new SelectListItem {Text = x.ToDescription(), Value = x.ToString()}))
こうすることで、ドロップダウンに列挙値ではなく説明が表示されることが期待できます。また、編集に関しては、ページを投稿した後、選択した値をドロップダウンしてモデルを更新します。
他の人がすでに言ったように-状況に応じて異なる列挙型にバインドする必要がない限り、列挙型にデータバインドしないでください。これにはいくつかの方法があります。以下に例をいくつか示します。
ObjectDataSource
ObjectDataSourceでそれを行う宣言的な方法。まず、DropDownListをバインドするリストを返すBusinessObjectクラスを作成します。
public class DropDownData
{
enum Responses { Yes = 1, No = 2, Maybe = 3 }
public String Text { get; set; }
public int Value { get; set; }
public List<DropDownData> GetList()
{
var items = new List<DropDownData>();
foreach (int value in Enum.GetValues(typeof(Responses)))
{
items.Add(new DropDownData
{
Text = Enum.GetName(typeof (Responses), value),
Value = value
});
}
return items;
}
}
次に、このBOクラスを指すようにASPXページにHTMLマークアップを追加します。
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="ObjectDataSource1" DataTextField="Text" DataValueField="Value">
</asp:DropDownList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetList" TypeName="DropDownData"></asp:ObjectDataSource>
このオプションではコードビハインドは必要ありません。
DataBindの背後にあるコード
ASPXページのHTMLを最小化し、コードビハインドでバインドするには:
enum Responses { Yes = 1, No = 2, Maybe = 3 }
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
foreach (int value in Enum.GetValues(typeof(Responses)))
{
DropDownList1.Items.Add(new ListItem(Enum.GetName(typeof(Responses), value), value.ToString()));
}
}
}
とにかく、コツはGetValuesやGetNamesなどのEnum型のメソッドを機能させることです。
ASP.NETでそれを行う方法はわかりませんが、この投稿を確認してください...役立つかもしれません。
Enum.GetValues(typeof(Response));
あなたはlinqを使うことができます:
var responseTypes= Enum.GetNames(typeof(Response)).Select(x => new { text = x, value = (int)Enum.Parse(typeof(Response), x) });
DropDownList.DataSource = responseTypes;
DropDownList.DataTextField = "text";
DropDownList.DataValueField = "value";
DropDownList.DataBind();
public enum Color
{
RED,
GREEN,
BLUE
}
ddColor.DataSource = Enum.GetNames(typeof(Color));
ddColor.DataBind();
回答6を使用した汎用コード。
public static void BindControlToEnum(DataBoundControl ControlToBind, Type type)
{
//ListControl
if (type == null)
throw new ArgumentNullException("type");
else if (ControlToBind==null )
throw new ArgumentNullException("ControlToBind");
if (!type.IsEnum)
throw new ArgumentException("Only enumeration type is expected.");
Dictionary<int, string> pairs = new Dictionary<int, string>();
foreach (int i in Enum.GetValues(type))
{
pairs.Add(i, Enum.GetName(type, i));
}
ControlToBind.DataSource = pairs;
ListControl lstControl = ControlToBind as ListControl;
if (lstControl != null)
{
lstControl.DataTextField = "Value";
lstControl.DataValueField = "Key";
}
ControlToBind.DataBind();
}
この答えを見つけた後、私はこれを行うためのより良い(少なくともよりエレガントな)方法であると思いました。ここに戻ってそれを共有すると思いました。
Page_Load:
DropDownList1.DataSource = Enum.GetValues(typeof(Response));
DropDownList1.DataBind();
LoadValues:
Response rIn = Response.Maybe;
DropDownList1.Text = rIn.ToString();
SaveValues:
Response rOut = (Response) Enum.Parse(typeof(Response), DropDownList1.Text);
これはおそらく古い質問です。しかし、これが私のやり方です。
モデル:
public class YourEntity
{
public int ID { get; set; }
public string Name{ get; set; }
public string Description { get; set; }
public OptionType Types { get; set; }
}
public enum OptionType
{
Unknown,
Option1,
Option2,
Option3
}
次に、ビューで:ドロップダウンを使用する方法を次に示します。
@Html.EnumDropDownListFor(model => model.Types, htmlAttributes: new { @class = "form-control" })
これにより、列挙リストのすべてが読み込まれます。お役に立てれば..
[Display(Name = "Option number one")] Option1,
それはあなたが探しているものではありませんが、役立つかもしれません:
http://blog.jeffhandley.com/archive/2008/01/27/enum-list-dropdown-control.aspx
このように使用して、すべてのlistControleを渡すことができるのはなぜですか。
public static void BindToEnum(Type enumType, ListControl lc)
{
// get the names from the enumeration
string[] names = Enum.GetNames(enumType);
// get the values from the enumeration
Array values = Enum.GetValues(enumType);
// turn it into a hash table
Hashtable ht = new Hashtable();
for (int i = 0; i < names.Length; i++)
// note the cast to integer here is important
// otherwise we'll just get the enum string back again
ht.Add(names[i], (int)values.GetValue(i));
// return the dictionary to be bound to
lc.DataSource = ht;
lc.DataTextField = "Key";
lc.DataValueField = "Value";
lc.DataBind();
}
使い方は次のように簡単です:
BindToEnum(typeof(NewsType), DropDownList1);
BindToEnum(typeof(NewsType), CheckBoxList1);
BindToEnum(typeof(NewsType), RadoBuuttonList1);
ASP.NETは、いくつかの機能が追加されて更新され、組み込みの列挙型を使用してドロップダウンできるようになりました。
Enum自体にバインドする場合は、次のようにします。
@Html.DropDownList("response", EnumHelper.GetSelectList(typeof(Response)))
Responseのインスタンスにバインドしている場合は、これを使用します。
// Assuming Model.Response is an instance of Response
@Html.EnumDropDownListFor(m => m.Response)
これは、LINQを使用したOrder a EnumおよびDataBind(Text and Value)to Dropdownの私のソリューションです
var mylist = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().ToList<MyEnum>().OrderBy(l => l.ToString());
foreach (MyEnum item in mylist)
ddlDivisao.Items.Add(new ListItem(item.ToString(), ((int)item).ToString()));
カスタムヘルパー「ASP.NET MVC-列挙型のDropDownListヘルパーの作成」の作成に関する私の投稿を確認してください。http: //blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc -creating-a-dropdownlist-helper-for-enums.aspx
コンボボックス(または他のコントロール)でよりユーザーフレンドリーな説明を使用する場合は、次の関数でDescription属性を使用できます。
public static object GetEnumDescriptions(Type enumType)
{
var list = new List<KeyValuePair<Enum, string>>();
foreach (Enum value in Enum.GetValues(enumType))
{
string description = value.ToString();
FieldInfo fieldInfo = value.GetType().GetField(description);
var attribute = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).First();
if (attribute != null)
{
description = (attribute as DescriptionAttribute).Description;
}
list.Add(new KeyValuePair<Enum, string>(value, description));
}
return list;
}
Description属性が適用された列挙型の例を次に示します。
enum SampleEnum
{
NormalNoSpaces,
[Description("Description With Spaces")]
DescriptionWithSpaces,
[Description("50%")]
Percent_50,
}
次に、バインドしてそのように制御します...
m_Combo_Sample.DataSource = GetEnumDescriptions(typeof(SampleEnum));
m_Combo_Sample.DisplayMember = "Value";
m_Combo_Sample.ValueMember = "Key";
このようにして、変数名のように見えなくても、ドロップダウンに好きなテキストを置くことができます
Extensionメソッドを使用することもできます。拡張機能に慣れていない場合は、VBおよびC#のドキュメントを確認することをお勧めします。
VB拡張:
Namespace CustomExtensions
Public Module ListItemCollectionExtension
<Runtime.CompilerServices.Extension()> _
Public Sub AddEnum(Of TEnum As Structure)(items As System.Web.UI.WebControls.ListItemCollection)
Dim enumerationType As System.Type = GetType(TEnum)
Dim enumUnderType As System.Type = System.Enum.GetUnderlyingType(enumType)
If Not enumerationType.IsEnum Then Throw New ArgumentException("Enumeration type is expected.")
Dim enumTypeNames() As String = System.Enum.GetNames(enumerationType)
Dim enumTypeValues() As TEnum = System.Enum.GetValues(enumerationType)
For i = 0 To enumTypeNames.Length - 1
items.Add(New System.Web.UI.WebControls.ListItem(saveResponseTypeNames(i), TryCast(enumTypeValues(i), System.Enum).ToString("d")))
Next
End Sub
End Module
End Namespace
拡張機能を使用するには:
Imports <projectName>.CustomExtensions.ListItemCollectionExtension
...
yourDropDownList.Items.AddEnum(Of EnumType)()
C#拡張:
namespace CustomExtensions
{
public static class ListItemCollectionExtension
{
public static void AddEnum<TEnum>(this System.Web.UI.WebControls.ListItemCollection items) where TEnum : struct
{
System.Type enumType = typeof(TEnum);
System.Type enumUnderType = System.Enum.GetUnderlyingType(enumType);
if (!enumType.IsEnum) throw new Exception("Enumeration type is expected.");
string[] enumTypeNames = System.Enum.GetNames(enumType);
TEnum[] enumTypeValues = (TEnum[])System.Enum.GetValues(enumType);
for (int i = 0; i < enumTypeValues.Length; i++)
{
items.add(new System.Web.UI.WebControls.ListItem(enumTypeNames[i], (enumTypeValues[i] as System.Enum).ToString("d")));
}
}
}
}
拡張機能を使用するには:
using CustomExtensions.ListItemCollectionExtension;
...
yourDropDownList.Items.AddEnum<EnumType>()
選択した項目を同時に設定したい場合は
items.Add(New System.Web.UI.WebControls.ListItem(saveResponseTypeNames(i), saveResponseTypeValues(i).ToString("d")))
と
Dim newListItem As System.Web.UI.WebControls.ListItem
newListItem = New System.Web.UI.WebControls.ListItem(enumTypeNames(i), Convert.ChangeType(enumTypeValues(i), enumUnderType).ToString())
newListItem.Selected = If(EqualityComparer(Of TEnum).Default.Equals(selected, saveResponseTypeValues(i)), True, False)
items.Add(newListItem)
むしろSystem.Enumに変換することで、intサイズと出力の問題が回避されます。たとえば、0xFFFF0000はuintとしては4294901760ですが、intとしては-65536になります。
TryCastおよびSystem.Enumは、Convert.ChangeType(enumTypeValues [i]、enumUnderType).ToString()(私の速度テストでは12:13)よりもわずかに高速です。
コンボボックスとドロップダウンリストを使用したasp.netとwinformsの両方のチュートリアル: C#WinFormsとAsp.NetでEnumをComboboxで使用する方法
願ってる
あなたはこれをずっと短くすることができます
public enum Test
{
Test1 = 1,
Test2 = 2,
Test3 = 3
}
class Program
{
static void Main(string[] args)
{
var items = Enum.GetValues(typeof(Test));
foreach (var item in items)
{
//Gives you the names
Console.WriteLine(item);
}
foreach(var item in (Test[])items)
{
// Gives you the numbers
Console.WriteLine((int)item);
}
}
}