【问题标题】:SelectListItem selected = true not working in viewSelectListItem selected = true 不在视图中工作
【发布时间】:2019-08-20 10:58:34
【问题描述】:

我有一个性别选择字段(--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'.

有人知道我做错了什么吗?

【问题讨论】:

  • 这仅在 IE9 中吗?不久前我遇到了类似的问题,但无法解决。
  • 它在任何浏览器中都不起作用。
  • 在我的回答中使用ViewData["gender"] = new SelectList(GetGender(), "Key", "Value", "Male");。您没有像我发布的那样使用它,而是将其混合在一起。
  • 是的,但在这种情况下,它的硬编码为“男性”,但我需要从 pm.Gender 中动态选择它。
  • 然后使用without the selectedValue,因为我已经发布了我的答案。模型活页夹将完成其余的工作。请阅读答案。

标签: c# asp.net-mvc


【解决方案1】:

我建议最好为 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>
}

输出

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

编辑

基于 cmets 在下面找到示例项目的链接

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

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

【讨论】:

  • 感谢您的回答。一旦我得到它的工作,我会通知你。
  • 在 MVC 4 中它不起作用!仍然选择列表中的第一项。
  • @Umitk 否决!!!你是认真的朋友吗?首先,这个问题在 3 年前得到了回答。您是否按照说明进行操作?它也适用于 MVC 4。
  • @Umitk FYI:我已经将一个演示项目上传到 github(使用 MVC 4 互联网应用程序模板)。运行该应用程序并从主页添加一个指向“MyView”的链接。这是github链接github.com/prashanth-t/DropdownDemo
  • 如果你可以编辑你的答案,我可以投票。现在我不允许投票。
【解决方案2】:

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

"这个问题背后的原因是 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 视图中执行以下操作。 仅使用以下构造函数,不使用任何 CSS 或新对象值

 @Html.DropDownList("paymentTypeList") 

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

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

【讨论】:

  • 谢谢!调试一个小时后,我找到了你的答案。这个错误非常烦人,几乎无法调试。
  • 谢谢。我花了一段时间才弄清楚这个!
【解决方案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");

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

在视图中:

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

【讨论】:

  • 好的。让我玩一下。我会尽快回复你。谢谢
  • 我在实施您的解决方案后更新了我的问题,但我仍然遇到异常。你能看看我做错了什么吗?谢谢
  • 您遇到的是由于语句不完整导致的编译器错误。 read here。我使用 Razor 视图,所以它以 @ 符号开头。请检查它是否是
【解决方案4】:

在控制器中试试这个:

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") %>

【讨论】:

  • 这似乎导致异常:c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\a2ddcf57\568ca5cc\App_Web_index.aspx.73c2a466.g30mf9nu .0.cs(423): 错误 CS1026:) 预期
  • 您在某处缺少一个结束括号。更正缺少的括号(在我未编辑的代码中没有括号)并让我知道它是否有效。
【解决方案5】:

试试这个;

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>

【讨论】:

    【解决方案6】:

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

    扩展方法:

    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;
        }    
    }
    

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

    示例代码:

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

    选择列表功能:

    private SelectList SetSelectedItemValue(SelectList source)
    {
       Category category = new Category();
    
        SelectListItem firstItem = new SelectListItem();
    
        int selectListCount = -1;
    
        if (source != null && source.Items != null)
        {
            System.Collections.IEnumerator cenum = source.Items.GetEnumerator();
    
            while (cenum.MoveNext())
            {
                if (selectListCount == -1)
                {
                    selectListCount = 0;
                }
    
                selectListCount += 1;
    
                category = (Category)cenum.Current;
    
                source.SetSelectedValue(category.Name);
    
                break;
            }
            if (selectListCount > 0)
            {
                foreach (SelectListItem item in source.Items)
                {
                    if (item.Value == cenum.Current.ToString())
                    {
                        item.Selected = true;
    
                        break;
                    }
                }
            }
        }
        return source;
    }
    

    您可以将其设为通用全包功能/扩展 - 但它对我来说是按原样工作的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多