Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC3 EnumDropdownList所选值_C#_Asp.net Mvc 3 - Fatal编程技术网

C# MVC3 EnumDropdownList所选值

C# MVC3 EnumDropdownList所选值,c#,asp.net-mvc-3,C#,Asp.net Mvc 3,有一些有用的扩展方法可用于在下拉列表中显示枚举。例如和 但我遇到了一个问题,即如果枚举用Description属性修饰,这些帮助程序就不起作用。第一个示例与Description属性完美结合,但它没有设置选定的值。第二个示例设置选定的值,但不使用description属性。因此,我需要将这两种方法结合到一个工作助手中,以正确地执行这两种操作。我有很多的变化来让它工作,但迄今为止没有成功。我尝试了几种方法来创建selectlist,但不知何故它忽略了Selected属性。在我的所有测试中,有一个项

有一些有用的扩展方法可用于在下拉列表中显示枚举。例如和

但我遇到了一个问题,即如果枚举用Description属性修饰,这些帮助程序就不起作用。第一个示例与Description属性完美结合,但它没有设置选定的值。第二个示例设置选定的值,但不使用description属性。因此,我需要将这两种方法结合到一个工作助手中,以正确地执行这两种操作。我有很多的变化来让它工作,但迄今为止没有成功。我尝试了几种方法来创建selectlist,但不知何故它忽略了Selected属性。在我的所有测试中,有一个项目的Selected属性设置为true,但该属性被忽略。 所以任何想法都是最受欢迎的

这是我尝试过的最新代码:

public static IEnumerable<SelectListItem> ToSelectList(Type enumType, string selectedItem)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
            var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description;
            var listItem = new SelectListItem
            {
                Value = ((int)item).ToString(),
                Text = title,
                Selected = selectedItem == item.ToString()
            };

            items.Add(listItem);
        }
        return items;

    }

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

        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : modelExpression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownListFor(modelExpression, ToSelectList(modelExpression.ReturnType, value.ToString()));
    }
公共静态IEnumerable to selectList(类型enumType,字符串selectedItem)
{
列表项=新列表();
foreach(Enum.GetValues(enumType)中的变量项)
{
FieldInfo fi=enumType.GetField(item.ToString());
var attribute=fi.GetCustomAttributes(typeof(DescriptionAttribute),true);
var title=attribute==null?item.ToString():((DescriptionAttribute)属性);
var listItem=新建SelectListItem
{
Value=((int)项).ToString(),
文本=标题,
Selected=selectedItem==item.ToString()
};
添加(列表项);
}
退货项目;
}
公共静态HtmlString EnumDropDownList2For(此HtmlHelper HtmlHelper,表达式模型表达式)
{
var typeOfProperty=modelExpression.ReturnType;
if(!typeOfProperty.IsEnum)
抛出新ArgumentException(string.Format(“类型{0}不是枚举”,typeOfProperty));
var值=htmlHelper.ViewData.Model==null
?默认值(t属性)
:modelExpression.Compile()(htmlHelper.ViewData.Model);
返回htmlHelper.DropDownListFor(modelExpression,ToSelectList(modelExpression.ReturnType,value.ToString());
}

我对实际设置了自定义值的枚举也有同样的问题

public enum Occupation
{
    [Description("Lorry driver")] LorryDriver = 10,
    [Description("The big boss")] Director = 11,
    [Description("Assistant manager")] AssistantManager = 12
}
我发现,当我使用DropDownListFor()时,它不会使用SelectListItem集合中的选定项来设置选定选项。相反,它选择一个选项,该选项的值等于我试图绑定到的属性(m=>m.occulation),为此,它使用枚举的.ToString()而不是枚举的实际整数值。最后我将SelectListItem的值设置为:

var listItem = new SelectListItem
{
    Value = item.ToString(), // use item.ToString() instead
    Text = title,
    Selected = selectedItem == item.ToString() // <- no need for this
};

我对实际设置了自定义值的枚举也有同样的问题

public enum Occupation
{
    [Description("Lorry driver")] LorryDriver = 10,
    [Description("The big boss")] Director = 11,
    [Description("Assistant manager")] AssistantManager = 12
}
我发现,当我使用DropDownListFor()时,它不会使用SelectListItem集合中的选定项来设置选定选项。相反,它选择一个选项,该选项的值等于我试图绑定到的属性(m=>m.occulation),为此,它使用枚举的.ToString()而不是枚举的实际整数值。最后我将SelectListItem的值设置为:

var listItem = new SelectListItem
{
    Value = item.ToString(), // use item.ToString() instead
    Text = title,
    Selected = selectedItem == item.ToString() // <- no need for this
};

总结一下有效的解决方案(至少对我而言):

我使用以下一组助手方法

public static IEnumerable<SelectListItem> ToSelectList(Type enumType, string selectedItem)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            var title = item.GetDescription();
            var listItem = new SelectListItem
            {
                Value = item.ToString(),
                Text = title,
                Selected = selectedItem == item.ToString()
            };

            items.Add(listItem);
        }
        return items;

    }

public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
    {
        string inputName = GetInputName(expression);
        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : expression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()));
    }

public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
            string name = GetInputName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);

        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetInputName(MethodCallExpression expression)
    {
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }

这适用于带或不带description属性的枚举,并设置正确的选定值。

要总结有效的解决方案(至少对我而言):

我使用以下一组助手方法

public static IEnumerable<SelectListItem> ToSelectList(Type enumType, string selectedItem)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            var title = item.GetDescription();
            var listItem = new SelectListItem
            {
                Value = item.ToString(),
                Text = title,
                Selected = selectedItem == item.ToString()
            };

            items.Add(listItem);
        }
        return items;

    }

public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
    {
        string inputName = GetInputName(expression);
        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : expression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()));
    }

public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
            string name = GetInputName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);

        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetInputName(MethodCallExpression expression)
    {
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }

这适用于带或不带description属性的枚举,并设置正确的选定值。

jsut更多信息:jsut更多信息:感谢您的回答。尽管你的代码实际上并不适用于我,但它确实帮助我解决了这个问题!我还是不确定到底是什么让我变戏法了。。我根据您的评论修改了ToSelectList函数,并将其与GetDescription方法相结合。谢谢您的回答。尽管你的代码实际上并不适用于我,但它确实帮助我解决了这个问题!我还是不确定到底是什么让我变戏法了。。我根据您的评论修改了我的ToSelectList函数,并将其与GetDescription方法相结合。您缺少GetDescription()(很容易从上面的Zeno复制),但是
htmlHelper.DropDownList
在我的MVC3项目中未定义,VS不知道在哪里可以找到它(我已经
使用System.Web.Mvc
)所以我不确定有什么问题。该方法的名称空间是什么?您缺少GetDescription()(很容易从上面的Zeno复制),但是我的MVC3项目中没有定义
htmlHelper.DropDownList
,VS不知道在哪里可以找到它(我已经
使用System.Web.Mvc
),所以我不确定问题出在哪里。该方法的名称空间是什么?