MVC5 Razor html.dropdownlistfor set 当值在数组中时被选中
Posted
技术标签:
【中文标题】MVC5 Razor html.dropdownlistfor set 当值在数组中时被选中【英文标题】:MVC5 Razor html.dropdownlistfor set selected when value is in array 【发布时间】:2016-09-21 07:50:44 【问题描述】:我正在使用 C# 和 .NET Framework 4.6.1 开发一个 ASP.NET MVC 5 应用程序。
我有这个View
:
@model MyProject.Web.API.Models.AggregationLevelConfViewModel
[...]
@html.DropDownListFor(m => m.Configurations[0].HelperCodeType, (SelectList)Model.HelperCodeTypeItems, new id = "Configurations[0].HelperCodeType" )
ViewModel
是:
public class AggregationLevelConfViewModel
private readonly List<GenericIdNameType> codeTypes;
private readonly List<GenericIdNameType> helperCodeTypes;
public IEnumerable<SelectListItem> CodeTypeItems
get return new SelectList(codeTypes, "Id", "Name");
public IEnumerable<SelectListItem> HelperCodeTypeItems
get return new SelectList(helperCodeTypes, "Id", "Name");
public int ProductionOrderId get; set;
public string ProductionOrderName get; set;
public IList<Models.AggregationLevelConfiguration> Configurations get; set;
public AggregationLevelConfViewModel()
// Load CodeTypes to show it as a DropDownList
byte[] values = (byte[])Enum.GetValues(typeof(CodeTypes));
codeTypes = new List<GenericIdNameType>();
helperCodeTypes = new List<GenericIdNameType>();
for (int i = 0; i < values.Length; i++)
GenericIdNameType cType = new GenericIdNameType()
Id = values[i].ToString(),
Name = EnumHelper.GetDescription((CodeTypes)values[i])
;
if (((CodeTypes)values[i]) != CodeTypes.NotUsed)
codeTypes.Add(cType);
helperCodeTypes.Add(cType);
而Models.AggregationLevelConfiguration
是:
public class AggregationLevelConfiguration
public byte AggregationLevelConfigurationId get; set;
public int ProductionOrderId get; set;
public string Name get; set;
public byte CodeType get; set;
public byte HelperCodeType get; set;
public int PkgRatio get; set;
public int RemainingCodes get; set;
我需要在这些属性中设置选定的值:
public IEnumerable<SelectListItem> CodeTypeItems
get return new SelectList(codeTypes, "Id", "Name");
public IEnumerable<SelectListItem> HelperCodeTypeItems
get return new SelectList(helperCodeTypes, "Id", "Name");
但我无法在new SelectList(codeTypes, "Id", "Name");
或new SelectList(helperCodeTypes, "Id", "Name");
中设置它,因为所选值在Configurations
数组中:字段AggregationLevelConfiguration.CodeType
和AggregationLevelConfiguration.HelperCodeType
。
我想我必须在视图中设置选定的值,但我不知道该怎么做。
如何设置选定的值?
【问题讨论】:
在循环中使用DropDownListFor()
是一个不幸的限制。您需要在每次迭代中生成一个新的MutliSelectList
(在构造函数中设置selectedValues
属性),或者(更好)使用EditorTemplate
for typeof AggregationLevelConfiguration
并将SelectList
作为@ 传递给模板987654339@
谢谢。我明白我必须使用东西,但我不知道如何使用它们。
我试图找到一个答案,我在大约 6 个月前给出了两个选项的代码,但没有任何运气。如果我找不到它,我会在一个小时左右添加一个答案 - 但以下应该有效 - @Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, new SelectList(Model.HelperCodeTypeItems, "Value", "Text", Model.Configurations[0].HelperCodeType, new ... )
我正在研究使用 jQuery 选择选项的解决方案。
是的,这行得通。谢谢。
【参考方案1】:
不幸的是,@Html.DropDownListFor()
在循环中渲染控件时的行为与其他帮助程序略有不同。这之前已在 CodePlex 上报告为问题(不确定是错误还是限制)
有 2 个选项可以解决这个问题,以确保根据模型属性选择正确的选项
选项 1(使用 EditorTemplate
)
为集合中的类型创建自定义EditorTemplate
。在/Views/Shared/EditorTemplates/AggregationLevelConfiguration.cshtml
中创建一个partial(注意名称必须与类型的名称匹配
@model yourAssembly.AggregationLevelConfiguration
@Html.DropDownListFor(m => m.HelperCodeType, (SelectList)ViewData["CodeTypeItems"])
.... // other properties of AggregationLevelConfiguration
然后在主视图中,将SelectList
传递给EditorTemplate
作为additionalViewData
@using (Html.BeginForm())
...
@Html.EditorFor(m => m.Configurations , new CodeTypeItems = Model.CodeTypeItems )
...
选项2(在每次迭代中生成一个新的SelectList
并设置selectedValue
)
在此选项中,您的属性CodeTypeItems
应该是IEnumerable<GenericIdNameType>
,而不是SelectList
(或者只是将codeTypes
设为公共属性)。然后在主视图中
@Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, new SelectList(Model.CodeTypeItems, "Id", "Name", Model.Configurations[0].HelperCodeType)
旁注:不需要使用new id = "Configurations[0].HelperCodeType"
- DropDownListFor()
方法已经生成了id
属性
【讨论】:
使用选项 2,您节省了我的时间!之前,我使用了一个 hacky javascript 循环来遍历我所有的 DropDownLists 并从隐藏字段中手动设置选定的值。【参考方案2】:我编写这个类是为了解决在 html 选择列表中选择选项时遇到的问题。我希望它可以帮助某人。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace Login_page.Models
public class HTMLSelect
public string id get; set;
public IEnumerable<string> @class get; set;
public string name get; set;
public Boolean required get; set;
public string size get; set;
public IEnumerable<SelectOption> SelectOptions get; set;
public HTMLSelect(IEnumerable<SelectOption> options)
public HTMLSelect(string id, string name)
this.id = id;
this.name = name;
public HTMLSelect(string id, string name, bool required, IEnumerable<SelectOption> options)
this.id = id;
this.name = name;
this.required = required;
private string BuildOpeningTag()
StringBuilder text = new StringBuilder();
text.Append("<select");
text.Append(this.id != null ? " id=" + '"' + this.id + '"' : "");
text.Append(this.name != null ? " name=" + '"' + this.name + '"' : "");
text.Append(">");
return text.ToString();
public string GenerateSelect(IEnumerable<SelectOption> options)
StringBuilder selectElement = new StringBuilder();
selectElement.Append(this.BuildOpeningTag());
foreach (SelectOption option in options)
StringBuilder text = new StringBuilder();
text.Append("\t");
text.Append("<option value=" + '"' + option.Value + '"');
text.Append(option.Selected != false ? " selected=" + '"' + "selected" + '"' + ">" : ">");
text.Append(option.Text);
text.Append("</option>");
selectElement.Append(text.ToString());
selectElement.Append("</select");
return selectElement.ToString();
public class SelectOption
public string Text get; set;
public Boolean Selected get; set;
public string Value get; set;
和
public IEnumerable<SelectOption> getOrderTypes()
List<SelectOption> orderTypes = new List<SelectOption>();
if (this.orderType == "OptionText")
orderTypes.Add(new SelectOption() Value = "1", Text = "OptionText", Selected = true );
else
orderTypes.Add(new SelectOption() Value = "2", Text = "OptionText2" );
并使用它:
@
Login_page.Models.HTMLSelect selectElement = new Login_page.Models.HTMLSelect("order-types", "order-types");
@Html.Raw(selectElement.GenerateSelect(Model.getOrderTypes()));
【讨论】:
【参考方案3】:我留下这个以防它帮助别人。我有一个非常相似的问题,没有一个答案有帮助。
我们在顶部看到了这一行:
IEnumerable<SelectListItem> exitFromTrustDeed = (ViewData["ExitFromTrustDeed"] as IEnumerable<string>).Select(e => new SelectListItem()
Value = e,
Text = e,
Selected = Model.ExitFromTrustDeed == e
);
然后在视图下方:
@Html.DropDownListFor(m => m.ExitFromTrustDeed, exitFromTrustDeed, new @class = "form-control" )
我们在我的 ViewData 中有一个与 lambda 表达式的选择器同名的属性,并且由于某种原因导致下拉菜单在没有选择任何选项的情况下呈现。
我们将 ViewData 中的名称更改为 ViewData["ExitFromTrustDeed2"]
,使其按预期工作。
虽然很奇怪。
【讨论】:
以上是关于MVC5 Razor html.dropdownlistfor set 当值在数组中时被选中的主要内容,如果未能解决你的问题,请参考以下文章
MVC5 Razor html.dropdownlistfor set 当值在数组中时被选中