asp.net-mvc asp.net mvc 3 预选 Html.DropDownListFor 不在书呆子晚餐中工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4800447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
asp.net mvc 3 pre-select Html.DropDownListFor not working in nerd dinner
提问by Jay
Learning about dropdown lists, Im trying to add a RSVP create page for nerddinner as in Scott Gu's blogwith a Html.DropDownListFor listing available dinners.
了解下拉列表后,我尝试为书呆子添加一个 RSVP 创建页面,如Scott Gu 的博客中所示,其中包含一个 Html.DropDownListFor 列出可用晚餐。
I can get the dropdown list populated but I cannot get the dropdown to pre select the value ("Sample Dinner 2") I want. Im using an initilizer to seed a few dinner objects in the db. The database is sql ce 4 using a EF 'code first approach'. Sorry I know this is a v common problem and hate to ask, but honestly have spent quite some time on this but cant get it to work:
我可以填充下拉列表,但无法通过下拉列表预先选择我想要的值(“Sample Dinner 2”)。我正在使用初始化程序在数据库中播种一些晚餐对象。数据库是 sql ce 4,使用 EF“代码优先方法”。抱歉,我知道这是一个常见问题,不想问,但老实说,我花了很多时间在这上面,但无法让它工作:
ViewModel
视图模型
public class RSVPViewModel
{
public SelectList DinnersList { get; set; }
public RSVP Rsvp { get; set; }
public string SelectedItem { get; set; }
}
Controller
控制器
//
//GET: /RSVP/Create
public ActionResult Create()
{
RSVP rsvp = new RSVP();
string selected = "Sample Dinner 2";
var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title", selected);
var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp, SelectedItem = selected };
return View("Create", viewModel);
}
View
看法
@Html.DropDownListFor(model => model.Rsvp.DinnerID, Model.DinnersList)
HTML Result
HTML 结果
<select data-val="true" data-val-number="The field DinnerID must be a number." data-val-required="The DinnerID field is required." id="Rsvp_DinnerID" name="Rsvp.DinnerID">
<option value="1">Sample Dinner 1</option>
<option value="2">Sample Dinner 2</option>
</select>
So is not preselecting the dropdownlist with the value "Sample Dinner 2" when the page loads. The list displays ok and sets the correct DinnerID when I make a selection and click Submit.
因此,在页面加载时不会预先选择值为“Sample Dinner 2”的下拉列表。当我进行选择并单击提交时,列表显示正常并设置正确的 DinnerID。
Tries this also:
也试试这个:
@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)
but doesnt set or bind to Rsvp.DinnerID.
但不设置或绑定到 Rsvp.DinnerID。
This preselects from the list but doesnt bind (or set Rsvp.DinnerID)
这从列表中预选但不绑定(或设置 Rsvp.DinnerID)
@Html.DropDownList("DinnersList")
I want to keep it mvc3 so want to implement with strong type using ViewModel approach (no ViewData) and preferably using Html.DropDownListFor (not Html.DropDownList).Viewbag seems unnecessary for this case.
我想保留它 mvc3 所以想使用 ViewModel 方法(无 ViewData)和最好使用 Html.DropDownListFor(不是 Html.DropDownList)以强类型实现。Viewbag 在这种情况下似乎是不必要的。
Thanks!
谢谢!
Edit1
编辑1
Thinking I should be using a selectList of selectListItems I tried this verbose approach :
认为我应该使用 selectListItems 的 selectList 我尝试了这种冗长的方法:
RSVP rsvp = new RSVP();
string selected = "2";
List<SelectListItem> dinners = new List<SelectListItem>();
foreach (Dinner dinner in dbc.Dinners.ToList())
{
SelectListItem slDinner = new SelectListItem();
slDinner.Value = dinner.DinnerID.ToString();
slDinner.Text = dinner.Title;
slDinner.Selected = (slDinner.Value == selected);
dinners.Add(slDinner);
}
var dinnersList = new SelectList(dinners, "Value", "Text", selected);
var viewModel = new RSVPViewModel { DinnersList = dinnersList, Rsvp = rsvp, SelectedItem = selected };
However still no work. Should I be making use of the ViewModel SelectedItem property in: @Html.DropDownListFor.. somehow? Something like :
然而仍然没有工作。我应该以某种方式使用 ViewModel SelectedItem 属性:@Html.DropDownListFor..?就像是 :
@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)
but how to I get a selected value to set Rsvp.DinnerID. I think thats called binding.
但是如何获得一个选定的值来设置 Rsvp.DinnerID。我认为这就是所谓的绑定。
采纳答案by Jay
After reading hereand here, I finally understand how HtmlDropDownlistFor automatically selects the correct item in the dropdown based on your model- selecting a dinnerID in RSVP (foreign key to dinner.dinnerID) will cause the dropdown containing list of Dinner.DinnerIDs to pre select that value. No need yetI think for selectedValue in the SelectList or ViewModel.
阅读here和here后,我终于明白HtmlDropDownlistFor如何根据您的模型自动选择下拉列表中的正确项目- 在RSVP中选择dinnerID(dinner.dinnerID的外键)将导致包含Dinner.DinnerIDs列表的下拉列表进行预选择那个值。我认为还不需要SelectList 或 ViewModel 中的 selectedValue。
Solution:
解决方案:
//
//GET: /RSVP/Create
public ActionResult Create()
{
//automatically preselects matching DinnerID in the Dinner dropdownlist
var rsvp = new RSVP {DinnerID = 2 };
var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title");
var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp};
return View("Create", viewModel);
}
回答by StriplingWarrior
The SelectList
constructoryou're using is supposed to provide the selected value, but you are providing the selected text. You may want to try:
您使用的SelectList
构造函数应该提供选定的值,但您提供的是选定的文本。您可能想尝试:
int selected = 2;
回答by David Steele
Html.DropDownList only works if the bound property is an int. Any other type, such as a named enum, will cause it to default to the first item.
Html.DropDownList 仅在绑定属性为 int 时才有效。任何其他类型,例如命名枚举,将导致它默认为第一项。
Add a property to your Model, type int, which wraps the enum you are trying to maintain:
向您的模型添加一个属性,键入 int,它包装您要维护的枚举:
public myEnumType myProperty {get; set;} // don't bind this to Html.DropDownList
public myEnumType myPropertyAsInt {
get {return (int)this.myProperty; }
set {this.myProperty = (myEnumType)value; }
} // bind this instead
No need to use Selected in your SelectList - Html.DropDownList will synchronise just fine.
无需在 SelectList 中使用 Selected - Html.DropDownList 将同步就好了。
回答by Ahmed Eid Yamany
Please take care if there is a QUERY STRINGwith same name, it will override that behavior, Not sure about HIDDEN FIELDS with same name.
如果有,请照顾查询字符串用相同的名称,它将覆盖该行为,不知道有关的隐藏字段具有相同的名称。
E.g.
例如
DropDownListForwill use the value of Query Stringof DinnerID if found
如果找到,DropDownListFor将使用DinnerID的查询字符串的值
回答by Rolf
Html.DropDownList accepts int properties, DropDownListFor too, but you have to be careful what you are doing. I examined the SelectExtensions.cs from ASP.NET MVC 3 and found this:
Html.DropDownList 接受 int 属性,DropDownListFor 也接受,但你必须小心你在做什么。我检查了 ASP.NET MVC 3 中的 SelectExtensions.cs 并发现了这个:
When you use DropDownList("XyField", "default") to create a DropDown, then you must place the select list into ViewBag.XyField and DropDownList() handles this correctly.
当您使用 DropDownList("XyField", "default") 创建 DropDown 时,您必须将选择列表放入 ViewBag.XyField 并且 DropDownList() 正确处理此问题。
When you use DropDownListFor(m=>m.XyField, ... ), you can pass the select list explictly, like this: DropDownListFor(m=>m.XyField, ViewBag.XyFieldListas IEnumerable)
当您使用 DropDownListFor(m=>m.XyField, ... ) 时,您可以显式传递选择列表,如下所示: DropDownListFor(m=>m. XyField, ViewBag. XyFieldListas IEnumerable)
When you do this, this following happen:
执行此操作时,会发生以下情况:
- The second parameter of DropDownListFor(...) will be used as source for the options
- If there is a ModelState entry for "XyField", this will be used as the model value
- If there is no model state AND Html.ViewData.Eval("XyField") returns not null, this value will be used as the model value.
- If the found model value is not null, it will be converted to a string, using CultureInfo.CurrentCulture, and this value is compared with your SelectListItem values to preselect the list options.
- DropDownListFor(...) 的第二个参数将用作选项的源
- 如果“XyField”有一个 ModelState 条目,这将用作模型值
- 如果没有模型状态且 Html.ViewData.Eval("XyField") 返回非 null,则此值将用作模型值。
- 如果找到的模型值不为空,则会使用 CultureInfo.CurrentCulture 将其转换为字符串,并将该值与您的 SelectListItem 值进行比较以预选列表选项。
Attention here: if you stored your select list in ViewBag.XyField, it will be found before the model is accessed.The don't want to compare "selectList.ToString()" with "selectList[i].Value" to preselect your options. Store your selection list in another place!
请注意:如果您将选择列表存储在 ViewBag.XyField 中,它将在访问模型之前找到。不想将“selectList.ToString()”与“selectList[i].Value”进行比较来预选您的选项。将您的选择列表存储在另一个地方!
The funny thing is, you CAN use DropDownListFor with an implicit select list, in the same way as you expect it from DropDownList(). In this case, you will even store your list in ViewBag.XyField. To make this work, you simply have to call the helper with null as second parameter: DropDownListFor(m=>m.XyField, null)
有趣的是,您可以将 DropDownListFor 与隐式选择列表一起使用,就像您对 DropDownList() 的期望一样。在这种情况下,您甚至会将您的列表存储在 ViewBag.XyField 中。要完成这项工作,您只需使用 null 作为第二个参数调用帮助程序: DropDownListFor(m=>m. XyField, null)
Then, the select list is pulled from ViewBag.XyField and step 3 in the list above is skipped. So, if XyField is in the model state, this will take precedence before your own Selected properties in the select list, but otherwise, the select list will be used "as is".
然后,从 ViewBag.XyField 中拉出选择列表,并跳过上面列表中的第 3 步。因此,如果 XyField 处于模型状态,则这将优先于选择列表中您自己的 Selected 属性,否则,将“按原样”使用选择列表。
Greetings Rolf
问候罗尔夫