SelectListItem selected = true在视图中不起作用

时间:2012-05-11 14:43:33

标签: c# asp.net-mvc

我有一个性别选择字段(--Select--,Male,Female),我正在我的控制器中填充它。加载页面时,我希望在页面加载时自动选择模型pm.Gender中选择的性别。

pm.Gender的值回复为:

  • “”
  • “M”
  • “F”

查看:

<%: Model.Gender %>
<%: Html.DropDownListFor(m => m.Gender, (IEnumerable<SelectListItem>)ViewData["gender"], new { @class = "span2" })%>

控制器:

gender = new[] { "Select", "Male", "Female" };
List<SelectListItem> genderselectList = new List<SelectListItem>();
foreach (string item in gender)
{
   SelectListItem sli = new SelectListItem { Text = item, Value = item };

   if (item.Trim().StartsWith(pm.Gender))
      sli.Selected = true;

   genderselectList.Add(sli);
}

ViewData["gender"] = genderselectList;

调试应用程序后,我可以看到genderselectList包含Selected = true的正确数据,以获取应该选择的正确值。但是当页面加载时,下拉列表中没有选择任何应该使用Html.DropDownListFor生成的内容。

修改:在任何浏览器中均无效。

任何人都知道可能导致此问题的原因是什么?任何帮助,将不胜感激。

干杯。

编辑:(实施Kaf解决方案后)
好的,这就是我在实施Kaf解决方案后正在做的事情。

查看:

<%: Html.DropDownListFor(m => m.Gender, (SelectList)(ViewData["gender"]), new { @class = "span2" }) %>

控制器:

gender = new[] { "Select", "Male", "Female" };
List<SelectList> genderselectList = new List<SelectList>();
foreach (string item in gender)
{
    SelectList sli;

    if (item.Trim().StartsWith(pm.Gender))
        sli = new SelectList(GetGender(), item, item, item); 
    else
        sli = new SelectList(GetGender(), item, item);
        //without selectedValue

    genderselectList.Add(sli);
}

ViewData["gender"] = genderselectList;

当我这样做时,我得到以下例外:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Web.Mvc.SelectList]' to type 'System.Web.Mvc.SelectList'.

任何人都知道我做错了什么?

6 个答案:

答案 0 :(得分:21)

我建议如果你对SelectList使用强类型属性(而不是使用ViewBag / ViewData)会更好。我相信您期望的是您的下拉列表是通过模型中的性别选择预先选择的。这是一个解决方案(代码不是100%干净。但这会起作用)

模型

public class TestModel
{
    public string Gender { get; set; }

    public IEnumerable<SelectListItem> GenderList
    {
        get
        {
            List<SelectListItem> list = new List<SelectListItem> { new SelectListItem() { Text = "Select", Value = "Select" }, new SelectListItem() { Text = "Male", Value = "Male" }, new SelectListItem() { Text = "Female", Value = "Female" } };
            return list.Select(l => new SelectListItem { Selected = (l.Value == Gender), Text = l.Text, Value = l.Value });
        }
    }
}

控制器操作

public ActionResult MyView()
{
    TestModel m = new TestModel();
    m.Gender = "Female";
    return View(m);
}

MyView.cshtml

@model TestModel

@{
    ViewBag.Title = "MyView";
}

<h2>MyView</h2>
@using (Html.BeginForm())
{
    <div>
          @Html.DropDownListFor(model => model.Gender, Model.GenderList)
    </div>
}

<强>输出

选择“女性”选项的下拉菜单

enter image description here

修改

根据评论,在下面找到示例项目的链接

1)https://github.com/prashanth-t/DropdownDemo_BareBones(使用MVC 4空模板。文件大小最小,最小)

2)https://github.com/prashanth-t/DropdownDemo(使用MVC 4互联网应用程序模板。文件大小更大)

答案 1 :(得分:3)

使用select获取性别的方法:

private Dictionary<string,string> GetGender(){
    Dictionary<string, string> myDic = new Dictionary<string, string>();
    myDic.Add(System.DBNull.Value.ToString(), "Select");
    myDic.Add("Male", "Male");
    myDic.Add("Female", "Female");
    return myDic;
}

在控制器中:

//without selectedValue
ViewData["gender"]  = new SelectList(GetGender(), "Key", "Value");

OR

//"Male" as selectedValue
ViewData["gender"]  = new SelectList(GetGender(), "Key", "Value", "Male");

在视图中:

Html.DropDownListFor(m => m.Gender, (SelectList)(ViewData["gender"]),
                        new { @class = "span2" })

答案 2 :(得分:2)

请在控制器中尝试此操作:

string[] gender = new string[] {"Male", "Female"};
string selectedGender = gender.Where(x => x.StartsWith(pm.gender)).FirstOrDefault();
ViewData["gender"] = new SelectList(gender, selectedGender);

在视图中:

<%: Html.Dropdownlist(x => x.Gender, ViewData["gender"], "Select") %>

答案 3 :(得分:1)

这是ASP.NET MVC Razor视图中的已知 bug 。根据已知的错误文档

此问题背后的原因是,asp.net MVC首先在下拉列表的名称和模型上的属性之间寻找匹配项。如果存在匹配项,则SelectList的选定值将被覆盖。只需更改下拉列表的名称即可解决此问题。

我在这里举一个小例子,您可以用它来测试分辨率。

 var paymentTypeList = new List<SelectListItem>
                {
                    new SelectListItem { Text = "Select Payment Type", Value = "NA" },
                    new SelectListItem { Text = "Card", Value = "Card" },
                    new SelectListItem { Text = "Paytm Wallet", Value = "Paytm Wallet" },
                    new SelectListItem { Text = "Cash", Value = "Cash", Selected = true },
                    new SelectListItem { Text = "Credit", Value = "Credit" },
                    new SelectListItem { Text = "Other", Value = "Other" }
                };
 ViewBag.paymentTypeList = paymentTypeList;

解决方案选项1(最简单)-在MVC视图中更改选择列表ID的声明ID名称,例如

@Html.DropDownList("paymentTypeListNew", (List<SelectListItem>)ViewBag.paymentTypeList, new { @class = "form-control select2 select1" })

解决方案2 :(仅使用与Viewbag / viewdata属性匹配的@ Html.DropDownList的单个构造函数)

要确保选中的项目(在本例中为现金)被选中,请在MVC Razor View中执行以下操作。 仅使用以下构造函数,而没有任何CSS或新的对象值

 @Html.DropDownList("paymentTypeList") 

现在,如果您担心无法初始化CSS,则需要以编程方式初始化CSS。例如,如果您使用的是Jquery,则可以使用

$("#paymentTypeList").addClass("form-control");
            $("#paymentTypeList").addClass("select2");

答案 4 :(得分:0)

试试这个;

public static List<SelectListItem> ListSexo { get; } = new List<SelectListItem>
    {
        new SelectListItem{Selected =true, Value="N", Text="Seleccione"},
        new SelectListItem{Value="F", Text="Femenino"},
        new SelectListItem{Value="M", Text="Masculino"}
    };

<select asp-for="Sexo" asp-items="Commons.ListSexo" class="form-control"></select>

答案 5 :(得分:0)

在为这个问题寻找答案之后-沿途我有一些提示,但这是最终的解决方案。它是一种扩展方法。我正在使用MVC 5 C#4.52作为目标。下面的代码将“选择”设置为“列表中的第一项”,因为这是我所需要的,您可能只希望传递一个字符串并跳过枚举-但我还想确保自己从数据库返回到我的SelectList。

  

扩展方法:

.highlight {
    background: yellow;
}

对于那些喜欢完全低谷的人(像我一样),这里是用法。 对象类别的字段定义为名称-此字段将在下拉列表中显示为文本。您可以在上面的代码中看到对Text属性的测试。

  

示例代码:

public static class SelectListextensions
{

    public static System.Web.Mvc.SelectList SetSelectedValue
(this System.Web.Mvc.SelectList list, string value)
    {
        if (value != null)
        {
            var selected = list.Where(x => x.Text == value).FirstOrDefault();
            selected.Selected = true;                
        }
        return list;
    }    
}
  

选择列表功能:

SelectList categorylist = new SelectList(dbContext.Categories, "Id", "Name");

SetSelectedItemValue(categorylist);

您可以将其设为通用的全包函数/扩展程序-但它对我来说仍然有效。