我正在尝试使用Html。下拉列表扩展方法,但不知道如何与枚举一起使用它。

假设我有一个这样的枚举:

public enum ItemTypes
{
    Movie = 1,
    Game = 2,
    Book = 3
}

我如何去创建一个下拉与这些值使用Html。下拉列表扩展方法?

或者我最好的办法是简单地创建一个for循环并手动创建Html元素?


当前回答

使用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);
}

其他回答

一个超级简单的方法来做到这一点-没有所有的扩展似乎过度的东西是:

你的枚举:

    public enum SelectedLevel
    {
       Level1,
       Level2,
       Level3,
       Level4
    }

在你的控制器内部,将Enum绑定到一个List:

    List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();

然后把它扔进ViewBag:

    ViewBag.RequiredLevel = new SelectList(myLevels);

最后简单地将它绑定到视图:

    @Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })

这是迄今为止我发现的最简单的方法,不需要任何扩展或任何疯狂的东西。

更新:见安德鲁斯下面的评论。

超文本标记语言DropDownListFor只需要一个IEnumerable,所以Prise的解决方案的替代方案如下。这将允许你简单地写:

@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())

[其中SelectedItemType是ItemTypes类型的模型上的字段,并且您的模型是非空的]

此外,您实际上不需要泛化扩展方法,因为您可以使用enumValue.GetType()而不是typeof(T)。

编辑:集成西蒙的解决方案在这里以及,并包括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();
    }
}

我遇到了同样的问题,发现了这个问题,并认为Ash提供的解决方案不是我要寻找的;与内置的HTML . dropdownlist()函数相比,必须自己创建HTML意味着更少的灵活性。

c# 3等使得这非常简单。我有一个名为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);

这将创建一个很好的ol' SelectList,可以像在视图中一样使用:

<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>

匿名类型和LINQ使它更加优雅。无意冒犯,阿什。:)

你也可以在Griffin.MvcContrib中使用我的自定义HtmlHelpers。以下代码:

@Html2.CheckBoxesFor(model => model.InputType) <br />
@Html2.RadioButtonsFor(model => model.InputType) <br />
@Html2.DropdownFor(model => model.InputType) <br />

生成:

https://github.com/jgauffin/griffin.mvccontrib

使用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);
}