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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10553593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:17:52  来源:igfitidea点击:

SelectListItem selected = true not working in view

c#asp.net-mvc

提问by Farhan Ahmad

I have a gender select field (--Select--, Male, Female) and I'm populating that in my controller. When the page loads, I want the gender that is selected in the model pm.Genderto be automatically selected when the page loads.

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

The values from pm.Gendercome back as:

返回的值pm.Gender如下:

  • " "
  • "M"
  • "F"
  • “ ”
  • “米”
  • “F”

View:

看法:

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

Controller:

控制器:

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;

After debugging the application, I can see that genderselectListcontains the proper data with Selected = truefor the proper value that is supposed to be selected. But when the page loads, nothing is selected in the dropdown list that was supposed to be generated with the Html.DropDownListFor.

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

Edit:Does not work in any browser.

编辑:不适用于任何浏览器。

Anyone know what could be causing this problem? Any help would be appreciated.

有谁知道是什么导致了这个问题?任何帮助,将不胜感激。

Cheers.

干杯。

EDIT: (After implementing Kaf's solution)
Ok so this is what I'm doing after implementing Kaf's solution.

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

View:

看法:

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

Controller:

控制器:

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;

When I do that, I get the following exception:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Web.Mvc.SelectList]' to type 'System.Web.Mvc.SelectList'.

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

Anyone know what I'm doing wrong?

有谁知道我做错了什么?

采纳答案by Prashanth Thurairatnam

I suggest it's better if you use strongly typed property for SelectList (rather than using ViewBag/ViewData). I believe what you are expecting is that your dropdownlist to be pre-selected with the gender selection made in the model. Here is a solution (code is not 100% clean. But this will work)

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

Model

模型

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

Controller Action

控制器动作

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

MyView.cshtml

我的视图.cshtml

@model TestModel

@{
    ViewBag.Title = "MyView";
}

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

OUTPUT

输出

dropdown with 'Female' option selected

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

enter image description here

在此处输入图片说明

EDIT

编辑

Based on comments find below links to sample projects

根据评论找到以下示例项目的链接

1) https://github.com/prashanth-t/DropdownDemo_BareBones(Using the MVC 4 empty template. Smaller file size with bare minimum)

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

2) https://github.com/prashanth-t/DropdownDemo(Using the MVC 4 internet application template. Bigger file size)

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

回答by ristonj

Try this instead in the controller:

在控制器中试试这个:

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

And in the view:

在视图中:

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

回答by Kaf

Method to get genders with 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;
}

In the controller:

在控制器中:

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

OR

或者

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

In the view:

在视图中:

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

回答by Delmirio Segura

Try this;

尝试这个;

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>

回答by vibs2006

This is a known bugin ASP.NET MVC Razor View. As per the known bug documentation

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

"The reason behind this problem is that asp.net MVC first looks for a match between the name of the drop down and property on the model. If there's a match, the selected value of the SelectList is overridden. Changing the name of the drop down is all it takes to remedy the issue."

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

I'm here giving a small example which you can use to test the resolution.

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

 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;

Resolution Option 1 (Easiest)- Change the Name of declaration id of select list id in MVC view e.g

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

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

Resolution 2: (Use only single constructor of @Html.DropDownList that matches viewbag/viewdata property)

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

To ensure that selected item (cash in this example) gets selected do the following in MVC Razor View. Use only the following constructor without any CSS or new object values

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

 @Html.DropDownList("paymentTypeList") 

Now if you are worried that you cannot initialize the CSS then you need to initialize the css programitally. For example if you are using Jquery then can you can use

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

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

回答by Ken

After searching myself for answer to this problem - I had some hints along the way but this is the resulting solution. It is an extension Method. I am using MVC 5 C# 4.52 is the target. The code below sets the Selection to the First Item in the List because that is what I needed, you might desire simply to pass a string and skip enumerating - but I also wanted to make sure I had something returned to my SelectList from the DB)

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

Extension Method:

扩展方法:

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

And for those who like the complete low down (like me) here is the usage. The object Category has a field defined as Name - this is the field that will show up as Text in the drop down. You can see that test for the Text property in the code above.

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

Example Code:

示例代码:

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

SetSelectedItemValue(categorylist);

select list function:

选择列表功能:

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

You can make this a Generic All Inclusive function / Extension - but it is working as is for me.

您可以将其设为通用的全包功能/扩展 - 但它对我来说是正常的。