2013-11-27 67 views
24

我在我的控制器中構建以下SelectList從選擇列表ASP.NET MVC下拉列表

var u = new NewUser(); 

u.UserTypeOptions = new SelectList(new List<SelectListItem> 
{ 
    new SelectListItem { Selected = true, Text = string.Empty, Value = "-1"}, 
    new SelectListItem { Selected = false, Text = "Homeowner", Value = ((int)UserType.Homeowner).ToString()}, 
    new SelectListItem { Selected = false, Text = "Contractor", Value = ((int)UserType.Contractor).ToString()}, 
}); 

return u; 

而且在我看來,顯示它是這樣的:

@Html.DropDownListFor(m => m.UserType, Model.UserTypeOptions) 

它看起來像我給它什麼應該是一個非常簡單的下拉列表中選擇一組有效的SelectListItem S,但是,而不是領有效<option>清單與良好的價值觀和文字,我得到這個:

<select data-val="true" data-val-range="A user type must be selected." data-val-range-max="2" data-val-range-min="1" data-val-required="The UserType field is required." id="UserType" name="UserType" class="input-validation-error"> 
    <option>System.Web.Mvc.SelectListItem</option> 
    <option>System.Web.Mvc.SelectListItem</option> 
    <option>System.Web.Mvc.SelectListItem</option> 
</select> 

是怎麼回事?據我所知,這應該工作。

+0

爲什麼在世界上,你會創建一個'SelectList',然後從它創建另一個'SeelctList'。並且設置'SelectListItem'的'Selected'屬性同樣毫無意義 - 它被HtmlHelper忽略 - 它屬性UserType的值決定了選擇的內容(唯一的時間是'Selected'屬性被尊重的時候是你創建的一個不綁定到你的模型的下拉列表(例如'@Html。DropDownList(「NotAProperty」,Model.UserTypeOptions)') –

回答

43

您缺少設置選擇列表本身的字段是文字。這就是爲什麼它在列表中的每個對象上執行.ToString()。你可以認爲,鑑於它是一個列表SelectListItem它應該足夠聰明來檢測這個......但事實並非如此。

u.UserTypeOptions = new SelectList(
    new List<SelectListItem> 
    { 
     new SelectListItem { Selected = true, Text = string.Empty, Value = "-1"}, 
     new SelectListItem { Selected = false, Text = "Homeowner", Value = ((int)UserType.Homeowner).ToString()}, 
     new SelectListItem { Selected = false, Text = "Contractor", Value = ((int)UserType.Contractor).ToString()}, 
    }, "Value" , "Text", 1); 

順便說一句,你可以使用任何類型的數組列表...然後只需設置將作爲文本和Value屬性的名稱。

我覺得這是更好地做這樣:

u.UserTypeOptions = new SelectList(
    new List<SelectListItem> 
    { 
     new SelectListItem { Text = "Homeowner", Value = ((int)UserType.Homeowner).ToString()}, 
     new SelectListItem { Text = "Contractor", Value = ((int)UserType.Contractor).ToString()}, 
    }, "Value" , "Text"); 

我刪除了-1項目,每個項目的設置選擇真/假。

然後,在你的看法:

@Html.DropDownListFor(m => m.UserType, Model.UserTypeOptions, "Select one") 

這樣一來,如果你設置「中選擇一個」項目,您沒有設置一個項目在選擇列表的選擇時,UserType將爲空( UserType需要是int?)。

如果需要的選擇設置選擇列表的項目之一,你可以使用:

u.UserTypeOptions = new SelectList(options, "Value" , "Text", userIdToBeSelected); 
+0

真的,真的,真的應該足夠聰明,弄清楚。這真正反映了像微軟這樣的框架設計師之間的愚蠢的開發者爭論。 –

+0

使用'new SelectList(...)'從第一個創建第二個相同的'IEnumerable '是沒有意義的額外開銷。 –

+0

而你最後的代碼片段顯然是錯誤的。使用DropDownListFor()方法綁定屬性時,SelectList構造函數的第4個選項將被忽略 - 它是確定所選內容的屬性值。 –

1

試試這個,

剛例如:

u.UserTypeOptions = new SelectList(new[] 
              { 
               new {ID="1",Name="name1"}, 
               new{ID="2",Name="name2"}, 
               new{ID="3",Name="name3"}, 
              }, 
          "ID", "Name", 1); 

或者

u.UserTypeOptions = new SelectList(new List<SelectListItem>{ 
        new SelectListItem { Selected = true, Text = string.Empty, Value = "-1"}, 
       new SelectListItem {Selected = false, Text = "Homeowner", Value = "2"}, 
       new SelectListItem{ Selected = false,Text = "Contractor", Value = "3"}, 
      },"Value","Text"); 
7

試試吧他在剃刀

@{ 
    var selectList = new SelectList(
     new List<SelectListItem> 
     { 
      new SelectListItem {Text = "Google", Value = "Google"}, 
      new SelectListItem {Text = "Other", Value = "Other"}, 
     }, "Value", "Text"); 
    } 

@Html.DropDownListFor(m => m.YourFieldName, selectList, "Default label", new { @class = "css-class" }) 

@Html.DropDownList("ddlDropDownList", selectList, "Default label", new { @class = "css-class" })