MVC - 设置SelectList的选定值

时间:2009-09-07 20:17:47

标签: c# asp.net-mvc

如何在没有选择值的情况下实例化SelectList后设置selectList的selectedvalue属性;

SelectList selectList = new SelectList(items, "ID", "Name");

我需要在此阶段后设置所选值

15 个答案:

答案 0 :(得分:65)

如果你有SelectList对象,只需遍历其中的项目并设置你想要的项目的“Selected”属性。

foreach (var item in selectList.Items)
{
  if (item.Value == selectedValue)
  {
    item.Selected = true;
    break;
  }
}

或者与Linq:

var selected = list.Where(x => x.Value == "selectedValue").First();
selected.Selected = true;

答案 1 :(得分:20)

这里的派对有点晚了,但这是多么简单:

ViewBag.Countries = new SelectList(countries.GetCountries(), "id", "countryName", "82");

这使用我的方法getcountries来填充一个名为countries的模型,显然你将用你的数据源替换它,模型等,然后将id设置为selectlist中的值。然后只需添加最后一个参数,在本例中为“82”以选择默认选定项目。

[编辑] 以下是在Razor中使用它的方法:

@Html.DropDownListFor(model => model.CountryId, (IEnumerable<SelectListItem>)ViewBag.Countries, new { @class = "form-control" })

希望这能节省一些时间。

答案 2 :(得分:13)

只需在mvc4中使用第三个参数选择值

@Html.DropDownList("CountryList", new SelectList(ViewBag.Countries, "Value", "Text","974"))

这里&#34; 974&#34;被选中值指定

在我的结果中,所选国家现在是qatar.in C#,如下所示

    foreach (CountryModel item in CountryModel.GetCountryList())
        {
            if (item.CountryPhoneCode.Trim() != "974")
            {
                countries.Add(new SelectListItem { Text = item.CountryName + " +(" + item.CountryPhoneCode + ")", Value = item.CountryPhoneCode });

            }
            else {


                countries.Add(new SelectListItem { Text = item.CountryName + " +(" + item.CountryPhoneCode + ")", Value = item.CountryPhoneCode,Selected=true });

            }
        }

答案 3 :(得分:9)

为什么要在创建列表后设置值?我猜您是在模型中而不是在视图中创建列表。我建议在模型中创建底层的可枚举,然后使用它来构建实际的SelectList:

<%= Html.DropDownListFor(m => m.SomeValue, new SelectList(Model.ListOfValues, "Value", "Text", Model.SomeValue)) %>

这样,您选择的值始终设置为视图呈现而不是之前。此外,您不必在模型中放置任何不必要的UI类(即SelectList),也不会意识到UI。

答案 4 :(得分:3)

Doug回答了我的问题......但我会解释我的问题究竟是什么,以及Doug如何帮我解决你可能遇到的问题。

我调用jquery $.post并用部分视图替换我的div,就像这样。

function AddNewAddress (paramvalue) {
    $.post(url, { param: paramvalue}, function(d) {
        $('#myDiv').replaceWith(d);
    });
}

当这样做时,出于某种原因,当我踏入我的模型时,我的选定值附属属性从未被设置,直到我进入视图它才进入范围。

那么,我之前有什么

@Html.DropDownListUnobtrusiveFor(model => model.CustomerAddresses[i].YearsAtAddress, Model.CustomerAddresses[i].YearsAtAddressSelectList, new {onchange = "return Address.AddNewAddress(this,'" + @Url.Action("AddNewAddress", "Address") + "'," + i + ")"})

然而,即使设置了Model.CustomerAddresses [i] .YearsAtAddressSelectList,它也没有设置所选的值。

之后......

 @Html.DropDownListUnobtrusiveFor(model => model.CustomerAddresses[i].YearsAtAddress, new SelectList(Model.CustomerAddresses[i].YearsAtAddressSelectList, "Value", "Text", Model.CustomerAddresses[i].YearsAtAddress), new { onchange = "return Address.AddNewAddress(this,'" + @Url.Action("AddNewAddress", "Address") + "'," + i + ")" })

并且工作了!

我决定不使用DropDownListFor,因为它在使用不引人注目的验证时有问题,这就是为什么我引用以下内容如果您对类中的好奇归类

HtmlExtensions.cs




[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]

public static MvcHtmlString DropDownListUnobtrusiveFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList)
{
    return DropDownListUnobtrusiveFor(htmlHelper, expression, selectList, null /* optionLabel */, null /* htmlAttributes */);

}


[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]

public static MvcHtmlString DropDownListUnobtrusiveFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes)
{
    return DropDownListUnobtrusiveFor(htmlHelper, expression, selectList, null /* optionLabel */, new RouteValueDictionary(htmlAttributes));

}


[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]

public static MvcHtmlString DropDownListUnobtrusiveFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
{
    return DropDownListUnobtrusiveFor(htmlHelper, expression, selectList, null /* optionLabel */, htmlAttributes);

}


[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]

public static MvcHtmlString DropDownListUnobtrusiveFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel)
{
    return DropDownListUnobtrusiveFor(htmlHelper, expression, selectList, optionLabel, null /* htmlAttributes */);

}


[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]

public static MvcHtmlString DropDownListUnobtrusiveFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
{
    return DropDownListUnobtrusiveFor(htmlHelper, expression, selectList, optionLabel, new RouteValueDictionary(htmlAttributes));

}


[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]

[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]

public static MvcHtmlString DropDownListUnobtrusiveFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
{
    if (expression == null)
    {
        throw new ArgumentNullException("expression");
    }


    ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);



    IDictionary<string, object> validationAttributes = htmlHelper
        .GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata);



    if (htmlAttributes == null)
        htmlAttributes = validationAttributes;
    else
        htmlAttributes = htmlAttributes.Concat(validationAttributes).ToDictionary(k => k.Key, v => v.Value);



    return SelectExtensions.DropDownListFor(htmlHelper, expression, selectList, optionLabel, htmlAttributes);

}

答案 5 :(得分:3)

继@Womp回答之后,值得注意的是&#34; Where&#34;可以删除,谓词可以放入&#34; First&#34;直接打电话,像这样:

list.First(x => x.Value == "selectedValue").Selected = true;

答案 6 :(得分:2)

我需要使用预先选定的下拉值在可编辑网格中下拉。 Afaik,选择列表数据由控制器提供给视图,因此它在视图消耗之前创建。一旦视图使用了SelectList,我就把它交给使用标准DropDownList帮助器的自定义帮助器。所以,一个相当轻松的解决方案imo。在编写本文时,猜测它符合ASP.Net MVC精神;当不高兴自己滚动...

public static string DropDownListEx(this HtmlHelper helper, string name, SelectList selectList, object selectedValue)
{
    return helper.DropDownList(name, new SelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField, selectedValue));
}

答案 7 :(得分:1)

您可以使用以下方法,这非常简单。

new SelectList(items, "ID", "Name",items.Select(x=> x.Id).FirstOrDefault());

这将自动选择列表中的第一项。您可以通过添加where子句来修改上述查询。

答案 8 :(得分:1)

我通常使用这种方法

        public static SelectList SetSelectedValue(SelectList list, string value)
    {
        if (value != null)
        {
            var selected = list.Where(x => x.Value == value).First();
            selected.Selected = true;
            return list;
        }
        return list;
    }

答案 9 :(得分:1)

我在这里结束了,因为SelectListItem不再正确选择所选值。要解决此问题,我将“ EditorFor”的用法更改为“手动”方法:

        <select id="Role" class="form-control">
            @foreach (var role in ViewBag.Roles)
            {
                if (Model.Roles.First().RoleId == role.Value)
                {
                    <option value="@role.Value" selected>@role.Text</option>
                }
                else
                {
                    <option value="@role.Value">@role.Text</option>
                }
            }
        </select>

希望它对某人有帮助。

答案 10 :(得分:0)

我希望下拉列表在action方法中选择id的匹配值。诀窍是在创建SelectListItem集合时设置Selected属性。它不会以任何其他方式工作,也许我错过了一些东西,但最终,我的选择更优雅。

您可以编写任何返回布尔值的方法,根据您的要求设置Selected值,在我的例子中,我使用现有的Equal方法

public ActionResult History(long id)
        {
            var app = new AppLogic();
            var historyVM = new ActivityHistoryViewModel();

            historyVM.ProcessHistory = app.GetActivity(id);
            historyVM.Process = app.GetProcess(id);
            var processlist = app.GetProcessList();

            historyVM.ProcessList = from process in processlist
                                    select new SelectListItem
                                    {
                                        Text = process.ProcessName,
                                        Value = process.ID.ToString(),
                                        Selected = long.Equals(process.ID, id)                                    

                                    };

            var listitems = new List<SelectListItem>();

            return View(historyVM);
        }

答案 11 :(得分:0)

下面的代码解决了两个问题:1)动态设置下拉列表的选定值; 2)更重要的是为模型中的索引数组创建下拉列表。这里的问题是每个人都使用选择列表的一个实例,即ViewBoag.List,而数组需要为每个下拉列表使用一个选择列表实例,以便能够设置所选值。

在控制器中将ViewBag变量创建为List(而非SelectList)

//控制器代码
ViewBag.Role = db.LUT_Role.ToList();

//在视图中 @ Html.DropDownListFor(m => m.Contacts [i] .Role,新的SelectList(ViewBag.Role,“ ID”,“ Role”,Model.Contacts [i] .Role))

答案 12 :(得分:0)

万一有人在找我,我将从以下位置转发我的答案: SelectListItem selected = true not working in view

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

Extension Method:

公共静态类SelectListextensions {

public static System.Web.Mvc.SelectList SetSelectedValue

(此System.Web.Mvc.SelectList列表,字符串值)     {         如果(值!=空)         {             var selected = list.Where(x => x.Text == value).FirstOrDefault();             selected.Selected = true;
        }         返回清单;     }
}

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

Example Code:

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

SetSelectedItemValue(categorylist);

select list function:

私有SelectList SetSelectedItemValue(SelectList源) {    类别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;

}

您可以将此功能设置为通用的全包功能/扩展程序-但这对我来说仍然有效

答案 13 :(得分:0)

使用LINQ并在“选定”项上添加条件作为问号条件。

    var listSiteId = (from site in db.GetSiteId().ToList()
                                      select new SelectListItem
                                      {
                                          Value = site.SITEID,
                                          Text = site.NAME,
                                          Selected = (dimension.DISPLAYVALUE == site.SITEID) ? true : false,
                                      }).ToList();
                    ViewBag.SiteId = listSiteId;

答案 14 :(得分:0)

这里有很多很好的答案,但也有很多不同的方法可以做到这一点。这是我的。

我认为这是所有“前端”DDL 代码(都在带有实体框架的 .NET MVC 中的 CSHTML 页面中——因此“Id”数据库引用,以及带有 jQ​​uery 前端验证的 Bootstrap 3 样式)。我还提到了“前端”,因为我没有显示任何模型注释或控制器/存储库/服务代码。

这是此 DDL 从中获取其值的 db 表:

enter image description here

它在 db 表中有一个默认值(“不适用”或 Id #4)这件事很烦人,但我不得不在现实世界中处理这个问题,所以希望这个例子有帮助。我在这个页面上的原因是为了解决这样的情况,一旦我想起了如何去做,我想我会在这里发布我所做的以防对其他人有帮助,因为其他答案不是就像这样。

好的,这是在“创建”表单上执行的操作,您将在其中创建初始对象。这就是为什么默认选择是 db 表中的 #4。

“创建”表单 DDL 示例

<div class="form-group">
    @Html.LabelFor(
      m => m.Survey.CountryId, 
      "North American Country you live in?", new 
@* .required is custom CSS class to add red asterisk after label *@
      { @class = "col-md-4 control-label required" }
    )
    <div class="col-md-8">
        @Html.DropDownListFor(
            m => m.Survey.CountryId,
            Model.Surveys.Select(i => new SelectListItem()
            {
                Value = i.Id.ToString(),
                Text = $"{i.Code} - {i.Description}",
/*  gave default selection of Id #4 in db table */
                Selected = i.Id == 4 ? true : false
            }), new
            {
                @class = "form-control",
                data_val = "true",
                data_val_required = "This is a required selection"
            })
        @Html.ValidationMessageFor(m => m.Survey.CountryId)
    </div>
</div>

“编辑”表单 DDL 示例


<div class="col-md-8">
    @Html.DropDownListFor(
        m => m.Survey.CountryId,
        Model.Surveys.Select(i => new SelectListItem()
        {
            Value = i.Id.ToString(),
            Text = $"{i.Code} - {i.Description}",
/* for Edit form, find the actual selected value the survey taker made */
            Selected = i.Id == Model.Survey.CountryId ? true : false
        }), new
        {
            @class = "form-control",
            data_val = "true",
            data_val_required = "This is a required selection"
        })
    @Html.ValidationMessageFor(m => m.Survey.CountryId)
</div>

你总是可以做一个这样的默认选择:

    @Html.DropDownListFor(
        m => m.Survey.CountryId,
        Model.Surveys.Select(i => new SelectListItem()
        {
            Value = i.Id.ToString(),
            Text = $"{i.Code} - {i.Description}",
            Selected = i.Id == Model.Survey.CountryId ? true : false
/* Add a default DDL selection when you're not trying to get it from a db */
        }), "-- select a country --", new
        {
            @class = "form-control"
        })

它应该是这样的:

这个 DDL 是针对“州”而不是“国家”,它有一个默认的“--选择--”选项,但更像是“编辑表单”版本,因为它已经被选中,现在显示该选项被检索来自数据库。

但除此之外...

enter image description here