it-swarm-ru.tech

Как связать Enum с элементом управления DropDownList в ASP.NET?

Допустим, у меня есть следующее простое перечисление:

enum Response
{
    Yes = 1,
    No = 2,
    Maybe = 3
}

Как можно связать это перечисление с элементом управления DropDownList, чтобы описания отображались в списке, а также извлекали соответствующее числовое значение (1,2,3) после выбора параметра?

117
Ray Vega

Я, вероятно, не буду связывать данные, так как они перечисляются, и они не изменятся после компиляции (если у меня не будет одного из этих Stoopid моменты).

Лучше просто перебрать перечисление:

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);
}
106
Mark Glorie

Используйте следующий служебный класс Enumeration для получения IDictionary<int,string> (Enum value & name name) из Enumeration; Затем вы связываете IDictionary с привязываемым элементом управления.

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();
69
Leyu

Я использую это для ASP.NET MVC:

Html.DropDownListFor(o => o.EnumProperty, Enum.GetValues(typeof(enumtype)).Cast<enumtype>().Select(x => new SelectListItem { Text = x.ToString(), Value = ((int)x).ToString() }))
40
Feryt

Моя версия - просто сжатая форма вышеупомянутого:

foreach (Response r in Enum.GetValues(typeof(Response)))
{
    ListItem item = new ListItem(Enum.GetName(typeof(Response), r), r.ToString());
    DropDownList1.Items.Add(item);
}
35
VanOrman
public enum Color
{
    RED,
    GREEN,
    BLUE
}

Каждый тип Enum происходит от System.Enum. Есть два статических метода, которые помогают привязать данные к элементу управления раскрывающегося списка (и получить значение). Это 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 Back on Selection ....

  private void ddColor_SelectedIndexChanged(object sender, System.EventArgs e)
  {
    Color selectedColor = (Color)Enum.Parse(typeof(Color),ddColor.SelectedValue
  }
22
user

После прочтения всех постов я предложил комплексное решение для поддержки отображения описания перечисления в раскрывающемся списке, а также выбора правильного значения в раскрывающемся списке Модель при отображении в режиме редактирования:

перечисление:

using System.ComponentModel;
public enum CompanyType
{
    [Description("")]
    Null = 1,

    [Description("Supplier")]
    Supplier = 2,

    [Description("Customer")]
    Customer = 3
}

класс расширения enum:

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()}))

Таким образом, вы можете ожидать, что ваш выпадающий список отображает описание вместо значений перечисления. Также, когда дело доходит до редактирования, ваша модель будет обновляться по выпадающему выбору значения после публикации страницы.

11
Amir Chatrbahr

Как уже говорили другие - не привязывайте данные к перечислению, если вам не нужно привязывать разные перечисления в зависимости от ситуации. Есть несколько способов сделать это, пара примеров ниже.

ObjectDataSource

Декларативный способ сделать это с ObjectDataSource. Сначала создайте класс BusinessObject, который будет возвращать List для привязки DropDownList к:

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;
    }
}

Затем добавьте HTML-разметку на страницу ASPX, чтобы указать на этот класс BO:

<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

Чтобы свернуть HTML-код на странице ASPX и выполнить связывание в Code Behind:

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()));
        }
    }
}

В любом случае, хитрость заключается в том, чтобы позволить типам Enum методов GetValues, GetNames и т.д. Работать за вас.

8
Johan Danforth

Я не уверен, как это сделать в ASP.NET, но посмотрите this post ... это может помочь?

Enum.GetValues(typeof(Response));
6
rudigrobler
Array itemValues = Enum.GetValues(typeof(TaskStatus));
Array itemNames = Enum.GetNames(typeof(TaskStatus));

for (int i = 0; i <= itemNames.Length; i++)
{
    ListItem item = new ListItem(itemNames.GetValue(i).ToString(),
    itemValues.GetValue(i).ToString());
    ddlStatus.Items.Add(item);
}
5
Adarsh

Вы можете использовать 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();
5
KrishnaDhungana
public enum Color
{
    RED,
    GREEN,
    BLUE
}

ddColor.DataSource = Enum.GetNames(typeof(Color));
ddColor.DataBind();
4
sankalp gurha

После нахождения этого ответа я придумал, как мне кажется, лучший (по крайней мере, более элегантный) способ сделать это, подумал, что вернусь и поделюсь этим здесь.

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);
3
Ben Hughes

Общий код с использованием ответа шесть.

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();

}
3
Muhammed Qasim

Это не совсем то, что вы ищете, но может помочь:

http://blog.jeffhandley.com/archive/2008/01/27/enum-list-dropdown-control.aspx

1
roman m

Это, наверное, старый вопрос ... но так я и сделал.

Модель:

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" })

Это должно заполнить все в вашем списке enum. Надеюсь это поможет..

1
Marie McDonley

С тех пор ASP.NET был дополнен некоторыми дополнительными функциями, и теперь вы можете использовать встроенное перечисление для раскрывающегося списка.

Если вы хотите привязать сам Enum, используйте это:

@Html.DropDownList("response", EnumHelper.GetSelectList(typeof(Response)))

Если вы привязываетесь к экземпляру Response, используйте это:

// Assuming Model.Response is an instance of Response
@Html.EnumDropDownListFor(m => m.Response)
1
bradlis7

Почему бы не использовать вот так, чтобы можно было передавать каждый 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);
1
Mostafa

Если вы хотите иметь более удобное для пользователя описание в поле со списком (или другим элементом управления), вы можете использовать атрибут 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";

Таким образом, вы можете поместить любой текст в раскрывающемся списке без необходимости выглядеть как имя переменной

0
Josh Stribling

Как asp.net, так и учебник winforms с выпадающим списком и выпадающим списком: Как использовать Enum с выпадающим списком в C # WinForms и Asp.Net

надежда помогает

0
justin

Прочтите мой пост о создании пользовательского помощника "ASP.NET MVC - Создание помощника DropDownList для перечислений": http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp -сетью-MVC-создание-а-DROPDOWNLIST-хелпер-для-enums.aspx

0
Stuart Leeks

Это мое решение для заказа выпадающего списка Enum и DataBind (текст и значение) с помощью LINQ

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()));
0
Diego Mendes

Принятое решение не работает, но приведенный ниже код поможет другим, ищущим самое короткое решение.

 foreach (string value in Enum.GetNames(typeof(Response)))
                    ddlResponse.Items.Add(new ListItem()
                    {
                        Text = value,
                        Value = ((int)Enum.Parse(typeof(Response), value)).ToString()
                    });
0
Hakan Erdogan

Вы также можете использовать методы расширения. Для тех, кто не знаком с расширениями, я предлагаю проверить документацию 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 будет 4294901760 как uint, но будет -65536 как int.

TryCast и System.Enum немного быстрее, чем Convert.ChangeType (enumTypeValues ​​[i], enumUnderType) .ToString () (12:13 в моих тестах скорости).

0
Trisped