【问题标题】:asp.net mvc 3 pre-select Html.DropDownListFor not working in nerd dinnerasp.net mvc 3 预选 Html.DropDownListFor 不在书呆子晚餐中工作
【发布时间】:2023-03-03 10:56:01
【问题描述】:

了解下拉列表,我尝试为 nerddinner 添加一个 RSVP 创建页面,如 Scott Gu's blog 中的 Html.DropDownListFor 列出可用的晚餐。

我可以填充下拉列表,但无法让下拉列表预先选择我想要的值(“样品晚餐 2”)。我使用初始化器在数据库中播种一些晚餐对象。该数据库是使用 EF '代码优先方法'的 sql ce 4。抱歉,我知道这是一个常见的问题,我不想问,但老实说,我在这方面花了很多时间,但无法让它发挥作用:

视图模型

public class RSVPViewModel
{
    public SelectList DinnersList { get; set; }
    public RSVP Rsvp { get; set; }
    public string SelectedItem { get; set; }
}

控制器

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

查看

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

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

也试试这个:

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

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

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

@Html.DropDownList("DinnersList")

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

谢谢!

编辑1

认为我应该使用 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。我认为这叫做绑定。

【问题讨论】:

  • 单步执行代码时,new SelectList(...) 生成的列表是否有 Selected 属性为 true 的项?
  • 我不确定你的意思。我没有在选择列表中使用 SelectListItems,所以我没有看到 Selected 属性?此外,我在其他地方(stackoverflow.com/questions/2410543/…)读到 Selected 属性在大多数情况下被忽略(可能适用于 @html.dropdownlist("DinnerList") 但没有绑定?
  • 我可以在 typeList 中看到一个 'SelectedValue' 属性,其值为 2,更改为下面的答案后类型为 int。

标签: asp.net-mvc asp.net-mvc-3 html.dropdownlistfor


【解决方案1】:

看完herehere,我终于明白了HtmlDropDownlistFor是如何自动在下拉列表中选择正确的项目根据你的模型——在RSVP中选择一个dinnerID(dinner.dinnerID的外键) ) 将导致包含 Dinner.DinnerIDs 列表的下拉列表预先选择该值。 我认为 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);
    }
【解决方案2】:

您使用的SelectList constructor 应该提供选定的值,但您提供的是选定的文本。你可以试试:

    int selected = 2;

【讨论】:

  • 那也没用。仍然默认为列表中的第一个元素。我检查了数据库以确保也存在一个晚餐 ID=2 的晚餐对象。
【解决方案3】:

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 会很好地同步。

【讨论】:

【解决方案4】:

如果有 QUERY STRING同名 ,请注意,它将覆盖该行为,不确定是否有同名的隐藏字段。

例如

DropDownListFor 将使用 DinnerID 的 Query String 的值,如果 找到了

【讨论】:

    【解决方案5】:

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

    当您使用 DropDownList("XyField", "default") 创建 DropDown 时,您必须将选择列表放入 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 属性,否则,选择列表将“按原样”使用。

    问候 罗尔夫

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多