Как связать Enum с элементом управления DropDownList в ASP.NET? - PullRequest
117 голосов
/ 15 сентября 2008

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

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

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

Ответы [ 23 ]

106 голосов
/ 15 сентября 2008

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

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

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);
}
69 голосов
/ 15 сентября 2008

Используйте следующий служебный класс Enumeration, чтобы получить IDictionary<int,string> (Enum value & name pair) из 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();
40 голосов
/ 10 марта 2010

Я использую это для 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() }))
35 голосов
/ 26 сентября 2008

Моя версия представляет собой просто сжатую форму выше:

foreach (Response r in Enum.GetValues(typeof(Response)))
{
    ListItem item = new ListItem(Enum.GetName(typeof(Response), r), r.ToString());
    DropDownList1.Items.Add(item);
}
22 голосов
/ 14 ноября 2008
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 возвращалось при выборе ....

  private void ddColor_SelectedIndexChanged(object sender, System.EventArgs e)
  {
    Color selectedColor = (Color)Enum.Parse(typeof(Color),ddColor.SelectedValue
  }
11 голосов
/ 16 июля 2014

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

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

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

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

8 голосов
/ 15 сентября 2008

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

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 и т. Д. Работали для вас.

6 голосов
/ 15 сентября 2008

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

Enum.GetValues(typeof(Response));
5 голосов
/ 18 ноября 2015

Вы можете использовать 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 голосов
/ 12 февраля 2009
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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...