在EditorTemplate中的DropDownListFor不select值
我有一个自定义对象的编辑器模板。 在那个编辑器模板里面,我使用了几个DropDownListFor帮助器。 在他们每个人中,我指定一个独特的模型属性(具有预先选定的值)和包含所有select选项的select列表。
例:
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
我知道选项值正在填充(从查看源),并且我的模型被传入正确的ID值(DocumentCategoryType)。
呈现视图时,下拉列表中没有选定的项目,因此它默认为第一个(未选定的)值。
有没有人有任何想法?
谢谢。
我们还通过填充一个新的SelectList
来解决这个问题,该SelectList
具有相应的SelectListItem
选项,但是创build了这个扩展方法来保持对DropDownListFor
的调用。
public static SelectList MakeSelection(this SelectList list, object selection) { return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection); }
然后你的DropDownListFor
调用变成:
<%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %>
通过ASP.NET MVC 2源代码展示了这个问题的一些解决scheme。 从本质上讲, SelectListItem
中的SelectList
在Selected
属性设置为true的helper扩展方法中传递,不会影响使用为该item selected
属性所呈现的<option>
元素。
<option>
元素上的selected
属性由<option>
确定
1)检查助手扩展方法是否通过了SelectList
。 如果这个值为null,那么框架将在ViewData中查找对应于您希望呈现其下拉列表的视图模型属性的键的值。 如果该值是一个SelectList
,那么只要模型属性的模型状态为null,这将用于呈现<select>
包括取任何选定的值。
2)如果在助手扩展方法中传递了SelectList
,并且model属性的模型状态为null,则框架将使用模型属性名称作为键在ViewData中查找默认值。 视图数据中的值被转换为一个string,并且传递给辅助方法扩展方法的SelectList
中的所有与默认值匹配的值(如果没有设置值,那么文本将被选中)将具有Selected
属性设置为true,这反过来将呈现具有selected="selected"
属性的<option>
。
综合起来,有两个合理的选项,我可以看到select一个选项,并使用强types的DropDownListFor
:
使用以下视图模型
public class CategoriesViewModel { public string SelectedCategory { get; private set ; } public ICollection<string> Categories { get; private set; } public CategoriesViewModel(string selectedCategory, ICollection<string> categories) { SelectedCategory = selectedCategory; Categories = categories; } }
选项1
在控制器中的ViewData中设置一个值,使您的视图与用于呈现下拉列表的集合的属性名称保持一致
控制器的行动
public class CategoriesController { [HttpGet] public ViewResult Select() { /* some code that gets data from a datasource to populate the view model */ ICollection<string> categories = repository.getCategoriesForUser(); string selectedCategory = repository.getUsersSelectedCategory(); CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories); this.ViewData["Categories"] = selectedCategory; return View(model); } [HttpPost] public ActionResult Select(CategoriesViewModel model) { /* some code that does something */ } }
并在强types的看法
<%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
选项2
使用所选项目的属性名称呈现下拉菜单
控制器的行动
public class CategoriesController { [HttpGet] public ViewResult Select() { /* some code that gets data from a datasource to populate the view model */ ICollection<string> categories = repository.getCategoriesForUser(); string selectedCategory = repository.getUsersSelectedCategory(); CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories); return View(model); } [HttpPost] public ActionResult Select(CategoriesViewModel model) { /* some code that does something */ } }
并在强types的看法
<%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>
它被确认为一个错误@ aspnet.codeplex.com,只对强types的视图行为。
解决方法:在视图代码中填充您的SelectList
喜欢
<%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) =>
呸。 我最终解决了这个问题。 我希望这被RTM固定。
<%if(Model!=null){ %> <%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%> <%}else{%> <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %> <%}%>
确保在将其发送到视图时将值分配给m.DocumentCategoryType。
一般来说,这个值会在你做回发时被重置,所以你只需要在返回到你的视图时指定值。
当创build一个下拉列表,你需要传递它的两个值。 1.这是您将存储选定值的位置2.是实际列表
例
<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
我犯了错误的设置select列表项目select值为True。 这不会做任何事情。 相反,只需在控制器中为m.DocumentCategoryType赋值,这实际上会为您select。
如果下拉列表的来源是IEnumerable而不是SelectList,那么这里有另一个好的解决scheme:
public static SelectList MakeSelection(this IEnumerable<SelectListItem> list, object selection, string dataValueField = "Value", string dataTextField = "Text") { return new SelectList(list, dataValueField, dataTextField, selection); }
Model.DocumentCategoryTypeList
这可能是你的问题。 在SelectListItems上,是否将值设置为.ToString()输出?
var list = new List<SelectListItem>() { new SelectListItem() { Value = Category.Book.ToString(), Text = "Book" }, new SelectListItem() { Value = Category.BitsAndPieces.ToString(), Text = "Bits And Pieces" }, new SelectListItem() { Value = Category.Envelope.ToString(), Text = "Envelopes" } };
这样做后为我工作。 它只需要能够匹配来自对象的值
我设法解释同样的问题说folling:
new SelectList(sections.Select(s => new { Text = s.SectionName, Value = s.SectionID.ToString() }), "Value", "Text")
这个技巧将转换为一个string的值。 我知道这已经在前面的答案中提到,但我觉得我的解决scheme有点清洁:)。 希望这可以帮助。
从我的项目中复制了na:
<%= Html.DropDownListFor(m => m.Profession.Profession_id, new SelectList(Model.Professions, "Profession_id", "Profession_title"),"-- Profession --")%>
通过的模型:
... public Profession Profession { get; set; } public IList<Profession> Professions { get; set; } ...
生成的Html:
<select id="Profession_Profession_id" name="Profession.Profession_id"> <option value="">-- Profesion --</option> <option value="4">Informatico</option> <option selected="selected" value="5">Administracion</option> </select>
为我工作。 我有这样的forms,唯一的缺点是,如果模型是无效的,我将模型返回到视图,我不得不重新加载专业列表。
obj.Professions = ProfileService.GetProfessions(); return View(obj);
我也有一个字段ProgramName这个问题。 原来,我们在BaseController和Layout.cshtml中使用了ViewBag.ProgramName,这是为了不同的目的。 由于ViewBag.ProgramName中的值未在下拉列表中find,因此即使SelectListItem.Selected对列表中的一个项目为true,也没有select任何值。 我们只是将ViewBag更改为使用不同的键,问题已解决。
这里是一个DropDownDownListForreplace ,只是从原来的MVC来源略有不同。
例:
<%=Html.FixedDropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
我很担心制作这么多的selectList的副本,所以相反,我添加selectedvalue作为自定义属性,然后使用jquery实际执行项目select:
@Html.DropDownListFor(item => item.AttendeeID, attendeeChoices, String.Empty, new { setselectedvalue = Model.AttendeeID }) ........ jQuery("select[setselectedvalue]").each(function () { e = jQuery(this); e.val(e.attr("setselectedvalue")); });