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

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

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

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

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


当前回答

我做了以下工作,并取得了成功:

在view.cshtml中:

@ model MyModel.cs

@Html.EnumDropDownListFor(m=>m.MyItemType )

模型中: MyModel.cs

MyItemType {get;设置;}

其他回答

这是我的helper方法。 我用这个:

var values = from int e in Enum.GetValues(typeof(TEnum))
             select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };

而不是:

var values = from TEnum e in Enum.GetValues(typeof(TEnum))
           select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
                     , Name = e.ToString() };

下面就是:

public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum)
        {
            throw new ArgumentException("self must be enum", "self");
        }

        Type t = typeof(TEnum);

        var values = from int e in Enum.GetValues(typeof(TEnum))
                     select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };

        return new SelectList(values, "ID", "Name", self);
    }

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

根据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/

我遇到了同样的问题,发现了这个问题,并认为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(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))