asp.net mvc 3 预选 Html.DropDownListFor 不在书呆子晚餐中工作

发布于 2024-10-14 10:46:07 字数 2901 浏览 1 评论 0原文

了解下拉列表,我尝试为 nerddinner 添加 RSVP 创建页面,如 Scott Gu 的博客,带有 Html.DropDownList 用于列出可用的晚餐。

我可以填充下拉列表,但无法让下拉列表预先选择我想要的值(“示例晚餐 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< /strong>

@Html.DropDownListFor(model => model.Rsvp.DinnerID, Model.DinnersList)

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>

因此,在页面加载时,不会预先选择值为“示例晚餐 2”的下拉列表。当我做出选择并单击提交时,列表显示正常并设置正确的晚餐 ID。

也尝试一下:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)

但没有设置或绑定到 Rsvp.DinnerID。

这从列表中预选但不绑定(或设置 Rsvp.DinnerID)

@Html.DropDownList("DinnersList")

我想保留它 mvc3 所以想使用 ViewModel 方法(无 ViewData)并最好使用 Html.DropDownListFor (不是 Html.DropDownList)来实现强类型。Viewbag 似乎对于这种情况是不必要的。

谢谢!

Edit1

认为我应该使用 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 };

但是仍然没有效果。我应该以某种方式使用 @Html.DropDownListFor.. 中的 ViewModel SelectedItem 属性吗?类似于:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)

但如何获取选定值来设置 Rsvp.DinnerID。我想这就是所谓的绑定。

Learning about dropdown lists, Im trying to add a RSVP create page for nerddinner as in Scott Gu's blog with a Html.DropDownListFor listing available dinners.

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:

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

<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.

Tries this also:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)

but doesnt set or bind to Rsvp.DinnerID.

This preselects from the list but doesnt bind (or set 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.

Thanks!

Edit1

Thinking I should be using a selectList of selectListItems I tried this verbose approach :

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 :

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList)

but how to I get a selected value to set Rsvp.DinnerID. I think thats called binding.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不气馁 2024-10-21 10:46:07

阅读此处这里,我终于明白了 HtmlDropDownlistFor 如何根据您的模型自动在下拉列表中选择正确的项目 - 选择晚餐 ID在RSVP(晚餐.dinnerID 的外键)中将导致包含晚餐.晚餐ID 列表的下拉列表预先选择该值。我认为 SelectList 或 ViewModel 中的 selectedValue 还不需要。

解决方案:

    //
    //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);
    }

After reading here and 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 yet I think for selectedValue in the SelectList or ViewModel.

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);
    }
花间憩 2024-10-21 10:46:07

您使用的 SelectList 构造函数是应该提供选定的值,但您正在提供选定的文本。您可能想尝试:

    int selected = 2;

The SelectList constructor you're using is supposed to provide the selected value, but you are providing the selected text. You may want to try:

    int selected = 2;
冷…雨湿花 2024-10-21 10:46:07

Html.DropDownList 仅在绑定属性为 int 时才有效。任何其他类型(例如命名枚举)都会导致它默认为第一项。

向您的模型添加一个属性,输入 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

无需在 SelectList 中使用 Selected - Html.DropDownList 会很好地同步。

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.

Add a property to your Model, type int, which wraps the enum you are trying to maintain:

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.

长发绾君心 2024-10-21 10:46:07

请注意是否存在具有相同名称查询字符串,它将覆盖该行为,不确定是否具有相同名称的隐藏字段。

例如

DropDownListFor 将使用 DiningID 的查询字符串的值,如果
找到了

Please take care if there is a QUERY STRING with same name , it will override that behavior, Not sure about HIDDEN FIELDS with same name.

E.g.

DropDownListFor will use the value of Query String of DinnerID if
found

心奴独伤 2024-10-21 10:46:07

Html.DropDownList 接受 int 属性,DropDownListFor 也接受,但你必须小心你在做什么。我检查了 ASP.NET MVC 3 中的 SelectExtensions.cs 并发现了这一点:

When you use DropDownList("XyField", "default") to create a DropDown, then you必须将选择列表放入 ViewBag.XyField 和 DropDownList() 句柄中这是正确的。

当您使用 DropDownListFor(m=>m.XyField, ... ) 时,您可以显式传递选择列表,如下所示:
DropDownListFor(m=>m.XyField, ViewBag.XyFieldList as IEnumerable)

当您执行此操作时,会发生以下情况:

  • DropDownListFor(...) 的第二个参数将用作选项的源
  • 如果存在“XyField”的 ModelState 条目,则该值将用作模型值
  • 如果没有模型状态并且 Html.ViewData.Eval("XyField") 返回不为 null,则该值将用作模型值。
  • 如果找到的模型值不为空,则会使用 CultureInfo.CurrentCulture 将其转换为字符串,并将该值与 SelectListItem 值进行比较以预选择列表选项。

注意:如果您将选择列表存储在 ViewBag.XyField 中,则在访问模型之前就会找到它。 不想将“selectList.ToString()”与“selectList[i”进行比较].Value”来预先选择您的选项。将您的选择列表存储在另一个地方!

有趣的是,您可以将 DropDownListFor 与隐式选择列表一起使用,就像您期望从 DropDownList() 中使用的方式一样。在这种情况下,您甚至可以将列表存储在 ViewBag.XyField 中。要实现此功能,您只需使用 null 作为第二个参数来调用帮助器:
DropDownListFor(m=>m.XyField, null)

然后,从 ViewBag.XyField 中提取选择列表,并跳过上面列表中的步骤 3。因此,如果 XyField 处于模型状态,则这将优先于选择列表中您自己的 Selected 属性,但否则,选择列表将“按原样”使用。

问候
罗尔夫

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:

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.

When you use DropDownListFor(m=>m.XyField, ... ), you can pass the select list explictly, like this:
DropDownListFor(m=>m.XyField, ViewBag.XyFieldList as 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.

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!

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)

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".

Greetings
Rolf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文