3

我有一个我正在尝试使用的扩展方法,您可以在其中使用枚举属性创建下拉列表,并设置所选项目:

public enum DefaultEnumSelectItemOptions
{
    AddDefaultItemIfEnumIsZero,
    ZeroEnumIsDefaultItem
}
public static SelectList ToSelectList(this object enumObj, DefaultEnumSelectItemOptions option = DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
{
    var asEnum = Enum.Parse(enumObj.GetType(), enumObj.ToString());
    var values = Enum.GetValues(enumObj.GetType());
    var dataItems = new List<Tuple<string, int>>();
    dataItems.Add(new Tuple<string, int>("Select One", -1));
    for (int i = 0; i < values.Length; i++)
    {
        int enumValue = (int)values.GetValue(i);
        if (enumValue == 0)
        {
            if (option != DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
            {
                dataItems.Add(new Tuple<string, int>(values.GetValue(i).ToString(), enumValue));
            }
        }
        else
        {
            dataItems.Add(new Tuple<string, int>(values.GetValue(i).ToString(), enumValue));
        }
    }
    var selectedItemValue = (int)enumObj;
    if (selectedItemValue == 0 && option == DefaultEnumSelectItemOptions.AddDefaultItemIfEnumIsZero)
    {
        selectedItemValue = -1;
    }
    return new SelectList(dataItems, "Item2", "Item1", selectedItemValue);
}

模型如下所示:

public enum PropertyTypes
{
    Unknown=0,
    Vehicle,
    Other
}

[DataContract]
public class Property : ClaimEntity
{
    [DataMember]
    public PropertyTypes PropertyType { get; set; }

    public Property()
    {
        this.PropertyType = PropertyTypes.Vehicle;
    }
}

最后,视图如下所示:

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

当我在扩展方法中设置断点时,它似乎是正确的,但选定的选项没有出现在 html 中。

下拉问题

我究竟做错了什么?

编辑我将其更改为SelectListItem按照建议使用,但是我仍然没有看到选择的值:

在此处输入图像描述

4

2 回答 2

7

实际上,我自己也遇到了这个确切的问题,并发现 DropDownListFor(和 DropDownList)助手对于他们自己的利益来说有点太聪明了。

即使你传入了其中一个的集合SelectListItemSelected = true帮助程序实际上会评估你的模型,对其执行 aConvert.ToString()并尝试匹配该值。如果它没有找到该值,它将不选择任何内容。

我个人认为这是 MVC 中的一个重大错误,他们似乎没有在 MVC4 中纠正这个错误。他们认为ToString()对象的方法将匹配下拉列表中的值(而不是显示文本)是完全错误的假设。

编辑:至于解决这个问题的方法......

  1. 更改您的ToString()方法以返回值并找出另一种获取显示文本的方法。
  2. 由于您使用的是枚举,因此您可以只为您的值和显示文本提供字符串版本。它仍然会很好地绑定。
  3. 建立自己的下拉菜单
于 2012-05-18T15:28:02.173 回答
0

如果有人感兴趣,我已经使用这种方法来创建我的下拉列表,它可以工作,但可能不是一个聪明的方法,因为我是 MVC 的新手。您需要检查 firstelement 的枚举值是否对应于任何有效的枚举并将其推送到选择列表方法重载中,但我很着急所以不这样做。

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

    public static class Extensions
    {
        public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement)
        {
            var typeOfProperty = modelExpression.ReturnType;
            if (!typeOfProperty.IsEnum)
            {
                throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty));
            }

            Dictionary<int, string> KeyValuePair = new Dictionary<int, string>();
            Array EnumValues = Enum.GetValues(typeOfProperty);
            foreach (var item in EnumValues)
            {
                KeyValuePair.Add((int)item, item.ToString());
            }

            var selectList = new SelectList(KeyValuePair, "Key", "Value");
            return htmlHelper.DropDownListFor(modelExpression, selectList, firstElement);
        }
    }

并在我的页面中使用它作为

Html.EnumDropDownListFor(m => m.AccountType, ContextConstants.defaultSelectionString)
于 2013-03-27T00:27:21.857 回答