C# 值位于数组中时所选集合的MVC5 Razor html.DropDownList
我正在开发一个ASP.NETMVC5应用程序,使用C#和.NETFramework 4.6.1 我有一个C# 值位于数组中时所选集合的MVC5 Razor html.DropDownList,c#,asp.net-mvc,razor,C#,Asp.net Mvc,Razor,我正在开发一个ASP.NETMVC5应用程序,使用C#和.NETFramework 4.6.1 我有一个视图: @model MyProject.Web.API.Models.AggregationLevelConfViewModel [...] @Html.DropDownListFor(m => m.Configurations[0].HelperCodeType, (SelectList)Model.HelperCodeTypeItems, new { id = "Configu
视图
:
@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);
}
}
}
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"); }
}
public IEnumerable CodeTypeItems
{
获取{returnnewselectlist(代码类型,“Id”,“Name”);}
}
公共IEnumerable HelperCodeTypeItems
{
获取{returnnewselectlist(helperCodeTypes,“Id”,“Name”);}
}
但是我不能在newselectlist(代码类型,“Id”,“Name”)中设置它代码>或新建选择列表(帮助代码类型,“Id”、“名称”)代码>因为所选值位于配置中
数组:字段AggregationLevelConfiguration.CodeType
和AggregationLevelConfiguration.HelperCodeType
我想我必须在视图中设置所选的值,但我不知道怎么做
如何设置所选值?不幸的是@Html.DropDownListFor()
在循环中呈现控件时,其行为与其他帮助程序略有不同。这以前在CodePlex上被报告为一个问题(不确定这是一个bug还是一个限制)
are 2选项可解决此问题,以确保根据模型特性选择正确的选项
选项1(使用编辑器模板
)
为集合中的类型创建自定义EditorTemplate
。在/Views/Shared/EditorTemplates/AggregationLevelConfiguration.cshtml
中创建分部文件(注意名称必须与类型名称匹配
@model yourAssembly.AggregationLevelConfiguration
@Html.DropDownListFor(m => m.HelperCodeType, (SelectList)ViewData["CodeTypeItems"])
.... // other properties of AggregationLevelConfiguration
然后在主视图中,将选择列表
传递给编辑器或模板
作为附加视图数据
@using (Html.BeginForm())
{
...
@Html.EditorFor(m => m.Configurations , new { CodeTypeItems = Model.CodeTypeItems })
...
选项2(在每次迭代中生成一个新的SelectList
,并设置selectedValue
)
在此选项中,您的属性CodeTypeItems
应该是IEnumerable
,而不是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
attribute,我编写该类是为了克服在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; }
}
}
我留下这个,以防它对其他人有帮助。我有一个非常类似的问题,没有一个答案对我有帮助
我们在顶部看到了这条线:
IEnumerable<SelectListItem> exitFromTrustDeed = (ViewData["ExitFromTrustDeed"] as IEnumerable<string>).Select(e => new SelectListItem() {
Value = e,
Text = e,
Selected = Model.ExitFromTrustDeed == e
});
我的ViewData中有一个与lambda表达式的选择器同名的属性,出于某种原因,该属性使下拉列表在不选择任何选项的情况下呈现
我们将ViewData中的名称更改为ViewData[“ExitFromTrustDeed2”]
,这使它按预期工作
但是很奇怪。在循环中使用DropDownListFor()
是一个不幸的限制。您需要在每次迭代中生成一个新的MutliSelectList
(在构造函数中设置selectedValues
属性),或者(更好),使用EditorTemplate
作为AggregationLevelConfiguration
的类型,并将SelectList
作为AdditionalViewData
传递给模板。我知道我必须使用一些东西,但我不知道如何使用它们。我正在试图找到一个关于这两个选项的代码的答案,大约6个月前但是运气不好。如果我找不到答案,我会在一个小时左右添加一个答案-但是下面的方法应该有效-@Html.DropDownListFor(m=>m.Configurations[0]。HelperCodeType,new SelectList(Model.HelperCodeTypeItems,“Value”,“Text”,Model.Configurations[0]。HelperCodeType,new{…})
我正在研究一个使用jQuery选择选项的解决方案。是的,这很有效。谢谢。使用选项2,您节省了我的一天!之前,我使用了一个黑客JavaScript循环来迭代我的所有下拉列表,并从隐藏字段手动设置所选值。
@{
Login_page.Models.HTMLSelect selectElement = new Login_page.Models.HTMLSelect("order-types", "order-types");
}
@Html.Raw(selectElement.GenerateSelect(Model.getOrderTypes()));
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" })