2010-07-28 29 views
5

我有這個在ASP.NET MVC視圖中填充下拉列表。ASP.NET MVC:DropDownListFor不選擇任何選項

<%= Html.DropDownListFor(model => model.Bikes, 
     Model.Bikes.Select(
     x => new SelectListItem { 
       Text = x.Name, 
       Value = Url.Action("Details", "Bike", new { bikeId = x.ID }), 
       Selected = x.ID == Model.ID, 
      })) %> 

調試這個我可以看到Selected屬性設置爲true當它應該是。但是,當渲染視圖時,列表中的選項都未被選中。我意識到這可以通過DropDownListFor的另一個重載來完成,但我真的想讓這個版本工作。

任何想法?

回答

5

您選擇的值不起作用的原因是因爲您將Url用作選項值,但在 Selected子句中指定了 Model.ID

嘗試這樣的:

<%= Html.DropDownListFor(
    model => model.Bikes, 
    new SelectList(Model.Bikes, "Id", "Name", Model.ID) 
)%> 

"Id"表示將用作選項值的屬性,而"Name"表示將用作選項標籤的屬性。

如果你想保留Url.Action你可以嘗試:

​​

你會發現,我倒的名稱和ID,因爲它似乎更符合邏輯使用模型ID作爲選項值。


UPDATE:

這不工作的原因是因爲你綁定到一個IEnumerable(該DropDownListFor助手的第一個參數)。當您使用相同model.Bikes收集這應該是一個標量屬性:

<%= Html.DropDownListFor(
    model => model.SelectedBikeValue, 
    Model.Bikes.Select(
     x => new SelectListItem { 
       Text = x.Name, 
       Value = Url.Action("Details", "Bike", new { bikeId = x.ID }), 
       Selected = x.ID == Model.ID, 
     } 
)) %> 

我對作爲選項值代表真不使用URL的話。

+0

請注意,在我原來的問題中,值是URL。 – 2010-07-28 11:35:26

+1

是的,我注意到了這一點,但是因爲這對我來說似乎是一個糟糕的主意,我倒過來了。順便說一下,這就是爲什麼你選擇的值不起作用。您將Model.Id作爲選定值傳遞,並使用URL作爲選項值。不好。我建議您將ID保留爲選項值,如有必要,請在您要提交的控制器操作中獲取相應的URL。我不認爲合理使用網址作爲選項值。 – 2010-07-28 11:39:02

+0

在我的原始代碼中,我不會將ID作爲選項值和URL作爲選項值傳遞。我正在做的是將值設置爲URL,然後使用應該適用於要選擇的項目的條件。是否真的有什麼令人信服的理由,爲什麼我不應該使用URL的值? – 2010-07-28 11:46:50

0

我對這個概念有太多的麻煩。當你不能通過它時,它會特別顯現出來。「name」屬性來自包含該對象屬性的模型,因爲這樣的對象名稱會自動添加到名稱中。這太瘋狂了。在浪費了很多時間試圖想出這個問題之後,我放棄了,寫下了我自己在這裏發佈的下拉式擴展。它非常簡單,而且工作得很好。

public static MvcHtmlString SimpleDropDown(this HtmlHelper helper, object attributes, IEnumerable<SelectListItem> items, bool disabled = false) 
    { 
     XElement e = new XElement("select", 
      items.Select(a => { 
       XElement option = new XElement("option", a.Text); 
       option.SetAttributeValue("value", a.Value); 
       if (a.Selected) 
        option.SetAttributeValue("selected", "selected"); 
       return option; 
      }) 
      ); 

     if (attributes != null) 
     { 
      Dictionary<string, string> values = (from x in attributes.GetType().GetProperties() select x).ToDictionary(x => x.Name, x => (x.GetGetMethod().Invoke(attributes, null) == null ? "" : x.GetGetMethod().Invoke(attributes, null).ToString())); 
      foreach(var v in values) 
       e.SetAttributeValue(v.Key, v.Value); 
     } 

     if (disabled) 
      e.SetAttributeValue("disabled", ""); 

     return new MvcHtmlString(e.ToString()); 
    } 

而且,我把標誌禁用作爲一個額外的參數,因爲如果你想通過屬性的標準列表匿名綁定到它,它可以是一個相當麻煩。

下面是我目前如何使用它的一個例子。我將一個字典翻譯成一個SelectListItem列表,但它可以只是一個簡單的列表。

@Html.SimpleDropDown(new { id="EOM", name = "EOM", @class = "topBox" }, Model.EOM.Select(x => new SelectListItem { Text = x.Value, Value = x.Key.ToString(), Selected = Model.EOM.Selected == x.Key }), !Model.EOM.Available)