我怎样才能得到这个ASP.NET MVC的SelectList工作?
我在我的控制器中创build一个selectList,以显示在视图中。
我试图在飞行中创build它,就像这样…
myViewData.PageOptionsDropDown = new SelectList(new [] {"10", "15", "25", "50", "100", "1000"}, "15");
它编译,但输出是坏的…
<select id="PageOptionsDropDown" name="PageOptionsDropDown"> <option>10</option> <option>15</option> <option>25</option> <option>50</option> <option>100</option> <option>1000</option> </select>
注意如何select项目?
我怎样才能解决这个问题?
这是我如何做到的
IList<Customer> customers = repository.GetAll<Customer>(); IEnumerable<SelectListItem> selectList = from c in customers select new SelectListItem { Selected = (c.CustomerID == invoice.CustomerID), Text = c.Name, Value = c.CustomerID.ToString() };
乍一看,我不确定我知道你在做什么…
我使用扩展方法:
用法
var departmentItems = departments.ToSelectList(d => d.Code + " - " + d.Description, d => d.Id.ToString(), " - "); var functionItems = customerFunctions.ToSelectList(f => f.Description, f => f.Id.ToString(), " - ");
同
public static class MCVExtentions { public static List<SelectListItem> ToSelectList<T>( this IEnumerable<T> enumerable, Func<T, string> text, Func<T, string> value, string defaultOption) { var items = enumerable.Select(f => new SelectListItem() { Text = text(f), Value = value(f) }).ToList(); items.Insert(0, new SelectListItem() { Text = defaultOption, Value = "-1" }); return items; } }
使用接受items, dataValueField, dataTextField, selectedValue
作为参数的构造函数:
ViewData["myList"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" } .Select(x => new {value = x, text = x}), "value", "text", "15");
那么在你看来:
<%=Html.DropDownList("myList") %>
构build托马斯· ToSelectList
的答案,我创build了这些重载的ToSelectList
方法:
using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; public static partial class Helpers { public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, bool selectAll = false) { return enumerable.ToSelectList(value, value, selectAll); } public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, object selectedValue) { return enumerable.ToSelectList(value, value, new List<object>() { selectedValue }); } public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, IEnumerable<object> selectedValues) { return enumerable.ToSelectList(value, value, selectedValues); } public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, bool selectAll = false) { foreach (var f in enumerable.Where(x => x != null)) { yield return new SelectListItem() { Value = value(f).ToString(), Text = text(f).ToString(), Selected = selectAll }; } } public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, object selectedValue) { return enumerable.ToSelectList(value, text, new List<object>() { selectedValue }); } public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, IEnumerable<object> selectedValues) { var sel = selectedValues != null ? selectedValues.Where(x => x != null).ToList().ConvertAll<string>(x => x.ToString()) : new List<string>(); foreach (var f in enumerable.Where(x => x != null)) { yield return new SelectListItem() { Value = value(f).ToString(), Text = text(f).ToString(), Selected = sel.Contains(value(f).ToString()) }; } } }
在您的控制器中,您可以执行以下操作:
var pageOptions = new[] { "10", "15", "25", "50", "100", "1000" }; ViewBag.PageOptions = pageOptions.ToSelectList(o => o, "15" /*selectedValue*/);
最后在你的观点中,把:
@Html.DropDownList("PageOptionsDropDown", ViewBag.PageOptions as IEnumerable<SelectListItem>, "(Select one)")
这将导致所需的输出 – 当然,如果您不想要第一个空项目,您可以省略上面的"(Select one)"
选项标签:
<select id="PageOptionsDropDown" name="PageOptionsDropDown"> <option value="">(Select one)</option> <option value="10">10</option> <option selected="selected" value="15">15</option> <option value="25">25</option> <option value="50">50</option> <option value="100">100</option> <option value="1000">1000</option> </select>
更新:修改后的代码清单可以在这里find XML注释。
问题是,SelectList按照devise工作。 该错误是在devise中。 你可以在SelectedItem中设置Selected Property,但是如果你使用GetEnumerator()(或者如果Mvc为你做的)遍历列表的话,这个选项将被忽略。 Mvc将创build新的SelectListItems。
你必须用SelectListItem [],Text-Name,Value-Name和SelectedValue来使用SelectList ctor。 注意传递SelectValue作为SelectListItem的值,而不是SelectListItem本身! 例:
SelectList sl = new SelectList( new[]{ new SelectListItem{ Text="one", Value="1"}, new SelectListItem{ Text="two", Value="2"}, new SelectListItem{ Text="three", Value="3"} }, "Text", "Value", "2" );
(没有testing过,但我有同样的问题)
那么第二个选项将得到selected =“selected”属性。 这看起来像旧的DataSets 😉
这是一个选项:
myViewData.PageOptionsDropDown = new[] { new SelectListItem { Text = "10", Value = "10" }, new SelectListItem { Text = "15", Value = "15", Selected = true } new SelectListItem { Text = "25", Value = "25" }, new SelectListItem { Text = "50", Value = "50" }, new SelectListItem { Text = "100", Value = "100" }, new SelectListItem { Text = "1000", Value = "1000" }, }
如果这是字面上所有你想要做的只是声明数组作为string修复选定的项目问题:
myViewData.PageOptionsDropDown = new SelectList(new string[] {"10", "15", "25", "50", "100", "1000"}, "15");
即使您的属性不是像Int,String或Double值这样的简单对象,获取SelectList和SelectedValue也是非常简单的。
例:
假设我们的Region对象是这样的:
public class Region { public Guid ID { get; set; } public Guid Name { get; set; } }
而你的视图模型是这样的:
public class ContactViewModel { public DateTime Date { get; set; } public Region Region { get; set; } public List<Region> Regions { get; set; } }
你可以有下面的代码:
@Html.DropDownListFor(x => x.Region, new SelectList(Model.Regions, "ID", "Name"))
只有当你覆盖Region对象的ToString方法,如下所示:
public class Region { public Guid ID { get; set; } public Guid Name { get; set; } public override string ToString() { return ID.ToString(); } }
这有100%保证工作。
但我真的相信SelectList 100%工作的最好方法是使用Equals方法对项目集合上的每个项目testingDropDownList或ListBox属性值。
看起来如果你有一个强types的视图,你需要改变下拉的ID,这样它就不是inheritance类的属性的名字。 然后,您需要在编辑(POST)方法中放入一些逻辑,从FORMCollection中提取选定的值,并在提交更改之前将其放到实例中。
这当然有点奇怪,但我试过了,它的工作原理。
因此,如果您的课程中有一个名为CountryId的字段,并且显示的是国家/地区名称列表,请使下拉列表中的国家/地区代码为CountryName而不是CountryId,然后在post中您可以使用Collection [“CountryName”] 。
我有完全相同的问题。 解决scheme很简单。 只需将传递给DropDownList助手的“name”参数更改为与ViewModel中存在的任何属性都不匹配的内容即可。 在这里阅读更多: http : //www.dotnetguy.co.uk/post/2009/06/25/net-mvc-selectlists-selected-value-does-not-get-set-in-the-view
我引用丹·沃森的话:
在MVC中,如果视图是强types的,则select列表的所选选项将被覆盖,并且在构造函数中设置的选项属性将永远不会到达视图,而下拉列表中的第一个选项将被选中(为什么仍然有点神秘) 。
干杯!
所有这些答案看起来不错,但似乎是控制器正在准备一个着名的结构化格式的视图的数据与让视图只是迭代通过模型交付的IEnumerable <>,并build立一个标准的select列表,然后让DefaultModelBinder通过操作参数将选定的项目传回给您。 是的,不,为什么不呢? 分离顾虑,是吗? 看起来很奇怪,让控制器来构buildUI和View特定的东西。
简单:
string[] someName = new string[] {"10", "15", "25", "50", "100", "1000"}; myViewData.PageOptionsDropDown = new SelectList(someName, "15");
使用你的例子,这为我工作:
控制器:
ViewData["PageOptionsDropDown"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15");
视图:
<%= Html.DropDownList("PageOptionsDropDown")%>
我只是像这样跑,没有问题,
public class myViewDataObj { public SelectList PageOptionsDropDown { get; set; } } public ActionResult About() { myViewDataObj myViewData = new myViewDataObj(); myViewData.PageOptionsDropDown = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15"); ViewData["myList"] = myViewData.PageOptionsDropDown; return View(); }
和
<%=Html.DropDownList("myList") %>
它也工作,如果你这样做,
public ActionResult About() { myViewDataObj myViewData = new myViewDataObj(); myViewData.PageOptionsDropDown = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }); ViewData["myListValues"] = myViewData.PageOptionsDropDown; ViewData["myList"] = "15"; return View(); }
和
<%=Html.DropDownList("myList",(IEnumerable<SelectListItem>)ViewData["myListValues"]) %>
MonthRepository monthRepository = new MonthRepository(); IQueryable<MonthEntity> entities = monthRepository.GetAllMonth(); List<MonthEntity> monthEntities = new List<MonthEntity>(); foreach(var r in entities) { monthEntities.Add(r); } ViewData["Month"] = new SelectList(monthEntities, "MonthID", "Month", "Mars");
我这样做:
List<SelectListItem> list = new List<SelectListItem>{ new SelectListItem {Selected = true, Text = "Select", Value = "0"}, new SelectListItem {Selected = true, Text = "1", Value = "1"}, new SelectListItem {Selected = true, Text = "2", Value = "2"} }; return list.ToArray();
ToArray()负责处理这些问题。
如果你想传递一些随机的文本到你的DropDownList,例如– select –你可以很容易地使用这个代码来做到这一点:
@Html.DropDownListFor(x => x.CategoryId, new SelectList(Model.Categories, "Id", "Name"), "--Select--", new { @class = "form-control" })
这可能是你的ViewData有些不明确的地方:
看看这里
在模型中select的值将利用而不是默认项目。 (我同意我没有阅读所有post)
我不记得mvc 1是如何设置的,但它似乎希望与它所属的字段名称相同的select列表…
我发现,正如上面所说的那样,我的select列表在mvc2中不起作用,当它们被发送的ViewData被命名为与字段相同时。
例如:
<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForName"]) %>
工作时
<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForID"]) %>
不起作用,因为ViewData名称“ForID”被命名为与其工作的字段相同
可能的解释是您绑定的selectlist值不是string。
那么在这个例子中,参数“PageOptionsDropDown”是你模型中的一个string? 因为如果不是,则列表中的选定值将不会显示。
如果您在Html.DropDownList扩展方法中查找MVC 2的源代码,它从不检查SelectList类SelectedValue属性。 它只会试图匹配你的模型。
以上所有内容都是关于主题的所有变体,也就是说,如何将一堆数据发送到视图以便下拉列表,并且它们彼此之间都是一样的(或多或less)。
问题在于。 您可以创build自己的DropDownList扩展方法,它可以尊重您设置的select值,也可以手动迭代。 哪个最适合你。
如果你在你的模型中有一个集合,而你的View是强types的,那么它的一些变化就会起作用:
@Html.DropDownListFor(x => x.RegionID, new SelectList(Model.Regions,"RegionID", "RegionName", Model.RegionID))
-要么-
@Html.DropDownList("RegionID", new SelectList(Model.Regions, "RegionID", "RegionName", Model.RegionID))