使用枚举填充DropDownListFor

时间:2013-10-23 11:11:52

标签: c# asp.net-mvc asp.net-mvc-3

我在MVC中有这样的模型:

public partial class Magazine
{           
    public int Id { get; set; }
    public int MagYear { get; set; }
    public int MagNo { get; set; }
    public string MagSeason { get; set; }
    public string MagYear2 { get; set; }    
}

我想在View中看到MagSeason有一个DropDownListFor并填充

  Enum Season
  {
 Spring =0,
 Summer =1,
 Autumn =2,
 Winter=3
  }

我应该怎么做?

2 个答案:

答案 0 :(得分:0)

开始编写您的自定义html帮助,如下所述 here ,然后根据需要更改模板

枚举

public enum Gender {
 [Display(Name="Male", Order=0)]
 Male,
 [Display(Name="Female", Order=1)]
 Female
}

查看

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

然后助手

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : System.ComponentModel.DisplayNameAttribute
{
    /// <summary>
    /// Sets the display name for an Enum field
    /// </summary>
    /// <param name="displayName">The display name value to use</param>
    public EnumDisplayNameAttribute(string displayName)
        : base(displayName)
    {
    }
}

public static class HtmlHelperExtensions
{
    public static MvcHtmlString EnumDropDownList<TEnumType>(this HtmlHelper htmlHelper, string name, TEnumType value)
    {
        var selectItems = GetSelectItemsForEnum(typeof(TEnumType), value);
        return htmlHelper.DropDownList(name, selectItems);
    }

    public static MvcHtmlString EnumDropDownListPlaceholder<TEnumType>(this HtmlHelper htmlHelper, string name, TEnumType value, string placeholderName = null)
    {
        var selectItems = GetSelectItemsForEnum(typeof(TEnumType), value);

        AddPlaceHolderToSelectItems(placeholderName, selectItems);
        return htmlHelper.DropDownList(name, selectItems, new { @class = "placeholder" });
    }




    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes = null) where TModel : class
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
            throw new InvalidOperationException("Expression must be a member expression");

        var name = ExpressionHelper.GetExpressionText(expression);
        var fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
        ModelState currentValueInModelState;
        var couldGetValueFromModelState = htmlHelper.ViewData.ModelState.TryGetValue(fullName, out currentValueInModelState);
        object selectedValue = null;
        if (!couldGetValueFromModelState &&
            htmlHelper.ViewData.Model != null)
        {
            selectedValue = expression.Compile()(htmlHelper.ViewData.Model);
        }

        var placeholderName = PlaceholderName(memberExpression);

        htmlAttributes = ApplyHtmlAttributes(htmlAttributes, placeholderName);

        var selectItems = GetSelectItemsForEnum(typeof(TProperty), selectedValue).ToList();
        AddPlaceHolderToSelectItems(placeholderName, selectItems);

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

    public static MvcHtmlString PlaceholderDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes = null)
        where TModel : class
    {
        var memberExpression = expression.Body as MemberExpression;
        if (memberExpression == null)
            throw new InvalidOperationException("Expression must be a member expression");

        IList<SelectListItem> list = selectList.ToList();
        var placeholderName = PlaceholderName(memberExpression);
        AddPlaceHolderToSelectItems(placeholderName, list);

        htmlAttributes = ApplyHtmlAttributes(htmlAttributes, placeholderName);

        return htmlHelper.DropDownListFor(expression, list, string.IsNullOrEmpty(optionLabel) ? null : optionLabel, htmlAttributes);
    }

    public static IList<SelectListItem> GetSelectItemsForEnum(Type enumType, object selectedValue)
    {
        var selectItems = new List<SelectListItem>();

        if (enumType.IsGenericType &&
            enumType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            enumType = enumType.GetGenericArguments()[0];
            selectItems.Add(new SelectListItem { Value = string.Empty, Text = string.Empty });
        }

        var selectedValueName = selectedValue != null ? selectedValue.ToString() : null;
        var enumEntryNames = Enum.GetNames(enumType);
        var entries = enumEntryNames
            .Select(n => new
            {
                Name = n,
                EnumDisplayNameAttribute = enumType
                    .GetField(n)
                    .GetCustomAttributes(typeof(EnumDisplayNameAttribute), false)
                    .OfType<EnumDisplayNameAttribute>()
                    .SingleOrDefault() ?? new EnumDisplayNameAttribute("")
            })
            .Select(e => new
            {
                Value = e.Name,
                DisplayName = e.EnumDisplayNameAttribute.DisplayName ?? e.Name

            })
            .OrderBy(e => e.DisplayName)
            .Select(e => new SelectListItem
            {
                Value = e.Value,
                Text = e.DisplayName,
                Selected = e.Value == selectedValueName
            });

        selectItems.AddRange(entries);

        return selectItems;
    }

    public static IEnumerable<string> GetNamesForEnum(Type enumType, object selectedValue)
    {
        if (enumType.IsGenericType &&
       enumType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            enumType = enumType.GetGenericArguments()[0];
        }

        var enumEntryNames = Enum.GetNames(enumType);
        var entries = enumEntryNames
            .Select(n => new
            {
                Name = n,
                EnumDisplayNameAttribute = enumType
                    .GetField(n)
                    .GetCustomAttributes(typeof(EnumDisplayNameAttribute), false)
                    .OfType<EnumDisplayNameAttribute>()
                    .SingleOrDefault() ?? new EnumDisplayNameAttribute("")
            })
            .Select(e => new
            {
                Value = e.Name,
                DisplayName = e.EnumDisplayNameAttribute.DisplayName ?? e.Name
            })
            .OrderBy(e => e.DisplayName)

            .Select(e => e.Value);
        return entries;
    }

    static string PlaceholderName(MemberExpression memberExpression)
    {
        var placeholderName = memberExpression.Member
            .GetCustomAttributes(typeof(EnumDisplayNameAttribute), true)
            .Cast<EnumDisplayNameAttribute>()
            .Select(a => a.DisplayName)
            .FirstOrDefault();
        return placeholderName;
    }

    static void AddPlaceHolderToSelectItems(string placeholderName, IList<SelectListItem> selectList)
    {
        if (!selectList.Where(i => i.Text == string.Empty).Any())
            selectList.Insert(0, new SelectListItem { Selected = false, Text = placeholderName, Value = string.Empty });

        if (!selectList.Any() || selectList[0].Text != string.Empty) return;

        selectList[0].Value = "";
        selectList[0].Text = placeholderName;
    }

    static IDictionary<string, object> ApplyHtmlAttributes(IDictionary<string, object> htmlAttributes, string placeholderName)
    {
        if (!string.IsNullOrEmpty(placeholderName))
        {
            if (htmlAttributes == null)
            {
                htmlAttributes = new Dictionary<string, object>();
            }

            if (!htmlAttributes.ContainsKey("class"))
                htmlAttributes.Add("class", "placeholder");
            else
            {
                htmlAttributes["class"] += " placeholder";
            }
        }
        return htmlAttributes;
    }

}

答案 1 :(得分:0)

查看我的博客文章

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

首先创建一个枚举助手

public static class EnumHelper
{
    //Creates a SelectList for a nullable enum value
    public static SelectList SelectListFor<T>(T? selected) where T : struct
    {
        return selected == null ? SelectListFor<T>()
                                : SelectListFor(selected.Value);
    }

    //Creates a SelectList for an enum type
    public static SelectList SelectListFor<T>() where T : struct
    {
        Type t = typeof (T);
        if (t.IsEnum)
        {
            var values = Enum.GetValues(typeof(T)).Cast<enum>()
                             .Select(e => new { 
                                            Id = Convert.ToInt32(e), 
                                            Name = e.GetDescription() 
                                          });

            return new SelectList(values, "Id", "Name");
        }
        return null;
    }

    //Creates a SelectList for an enum value
    public static SelectList SelectListFor<T>(T selected) where T : struct 
    {
        Type t = typeof(T);
        if (t.IsEnum)
        {
            var values = Enum.GetValues(t).Cast<Enum>()
                             .Select(e => new { 
                                            Id = Convert.ToInt32(e), 
                                            Name = e.GetDescription() 
                                          });

            return new SelectList(values, "Id", "Name", Convert.ToInt32(selected));
        }
        return null;
    } 

    // Get the value of the description attribute if the 
    // enum has one, otherwise use the value.
    public static string GetDescription<TEnum>(this TEnum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());

        if (fi != null)
        {
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
            {
                 return attributes[0].Description;
            }
        }

        return value.ToString();
    }
}

一旦你有了这个助手类,你就可以做到以下几点。

在您的控制器中:

//If you don't have an enum value use the type
ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>();

//If you do have an enum value use the value (the value will be marked as selected)
ViewBag.DropDownList = EnumHelper.SelectListFor(myEnumValue);

在您的视图中:

@Html.DropDownList("DropDownList")