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

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

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

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

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


当前回答

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

你的枚举:

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

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

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

其他回答

我遇到了同样的问题,发现了这个问题,并认为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使它更加优雅。无意冒犯,阿什。:)

所以没有扩展函数,如果你正在寻找简单和容易..这就是我所做的

<%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%>

where XXXXX.Sites.YYYY.Models.State是enum

也许做辅助函数更好,但是当时间很短的时候,这将完成工作。

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

你的枚举:

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

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

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

这里是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)

根据Simon的回答,类似的方法是从Resource文件中获取要显示的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();
}

枚举中的资源。Resx文件看起来像这样 ItemTypes_Movie:电影

我喜欢做的另一件事是,与其直接调用扩展方法,不如使用@Html调用它。EditorFor(x => x.MyProperty),或者理想情况下只有整个表单,在一个整洁的@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))
}

如果你对此感兴趣,我在我的博客上给出了更详细的答案:

http://paulthecyclist.com/2013/05/24/enum-dropdown/