如何创建MVC帮助器方法以从枚举中填充下拉列表

时间:2013-01-21 15:10:02

标签: asp.net-mvc razor

MVC HtmlHelper.DropDownFor方法可能非常令人沮丧。通常情况下,您的选择不会保留,或者您的控制没有正确绑定。您如何编写自定义HTML帮助程序来填充枚举下拉列表?

1 个答案:

答案 0 :(得分:1)

我花了最后几个小时试图弄清楚这个,所以不妨分享我发现的东西。在尝试各种排列,创建一个测试应用程序以尝试各种选项并搜索许多文章后,我得到了一些适合我的东西。

首先提一下。 SelectList类有四个参数(最后三个是可选的)。如果未指定所选值(最后一个参数),它将清除您在SelectListItem对象中设置的任何选定值(假设您创建了这些值的列表)。这让我感到沮丧,因为我将其中一个Selected属性设置为true,但是一旦我创建了SelectList对象,它总是设置为false。

以下是SelectList的MVC源代码供参考:

public class SelectList : MultiSelectList
{
    public SelectList(IEnumerable items)
        : this(items, null /* selectedValue */)
    {
    }

    public SelectList(IEnumerable items, object selectedValue)
        : this(items, null /* dataValuefield */, null /* dataTextField */, selectedValue)
    {
    }

    public SelectList(IEnumerable items, string dataValueField, string dataTextField)
        : this(items, dataValueField, dataTextField, null /* selectedValue */)
    {
    }

    public SelectList(IEnumerable items, string dataValueField, string dataTextField, object selectedValue)
        : base(items, dataValueField, dataTextField, ToEnumerable(selectedValue))
    {
        SelectedValue = selectedValue;
    }

    public object SelectedValue { get; private set; }

    private static IEnumerable ToEnumerable(object selectedValue)
    {
        return (selectedValue != null) ? new object[] { selectedValue } : null;
    }
}

一旦我超越了这一点,我得到了帮助,从列表中正确选择项目并正确绑定值。所以这里是我创建的辅助方法(初始方法来自另一篇文章,但这对我来说也没有正常工作):

public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null) where TProperty : struct, IConvertible
{
    if (!typeof(TProperty).IsEnum)
        throw new ArgumentException("TProperty must be an enumerated type");

    var selectedValue = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model.ToString();
    var selectList = new SelectList(from value in EnumHelper.GetValues<TProperty>()
                                    select new SelectListItem
                                                {
                                                    Text = value.ToDescriptionString(),
                                                    Value = value.ToString()
                                                }, "Value", "Text", selectedValue);

    return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
}

(EnumHelper.GetValues和ToDescriptionString是我的辅助方法,用于返回指定类型的枚举值列表,并获取枚举描述的EnumMember值属性)如果有人想要,我可以发布该代码它。

上面代码中的技巧告诉SelectList值和文本属性以及所选值。