2012-12-19 73 views
10

以下是相關的代碼。請注意,我在Notepad ++中完成了這項工作,而不是在我的代碼中複製我的項目。如果我拼錯了一個類名,假定它在我的代碼中沒有拼寫錯誤。沒有編譯錯誤。正確的方式使用DropDownListFor與原始類型的列表?

型號:

public class MyViewModel 
{ 
    public int SelectedSomething { get; set; } 

    public IList<int> Somethings { get; set; } 
} 

控制器:

public class MyController 
{ 
    public ActionResult Index() 
    { 
     var viewModel = new MyViewModel(); 
     viewModel.Somethings = Enumerable.Range(1, 12).ToList(); 
     return View(viewModel); 
    } 
} 

視圖(剃刀):

@Html.DropDownListFor(x => x.SelectedSomething, new SelectList(Model.Somethings, Model.SelectedSomething), "Select an Option") 

這將 「工作」,但不會對任何的設定值呈現option中的元素select

<select> 
    <option value="">Select an Option</option> 
    <option>1</option> 
    <option>2</option> 
    <option>3</option> 
    <option>4</option> 
    <option>5</option> 
    <option>6</option> 
    <option>7</option> 
    <option>8</option> 
    <option>9</option> 
    <option>10</option> 
    <option>11</option> 
    <option>12</option> 
</select> 

我知道需要在屬性名用來呈現在option元素valuetextSelectList constructor的,但它是沒有用的(,我可以看到)使用原始的集合時類型如int

問:

我知道我可以改變我的視圖模型的IList<int>IList<SelectListItem>,創造SelectListItem對象來表示每個int,但似乎有點可笑(我想構造不應該離開的價值空白,並應該默認使用文字)。我在這裏錯過了一些明顯的東西,還是我不得不在這裏使用原始類型?

@Html.DropDownListFor(x => x.SelectedSomething, 
         Model.Somethings.ToSelectList(n => n, v => v), 
         "Select an Option") 

對於int收集您可能需要使用n => n.ToString()您的姓名選擇:

回答

0

我使用擴展方法,可以讓你在你的看法寫這解決了這個問題。

這種方法的美妙之處在於您可以將它用於任何種類的枚舉。在您的示例中(帶有整數列表),我們只需指定返回元素本身的lambda表達式,這將導致文本和值在渲染選項列表中設置爲相同的值。

如果你想避免導入的擴展類的命名空間,你的web.config,聲明你的視圖模型,返回選擇列表的只讀屬性,然後訪問從您的視圖。

Web.config部分看起來像這樣(請注意,您需要爲程序集和命名空間創建一行)。另請注意,您的Views文件夾包含一個單獨的Web.config,它可能會覆蓋或擴展根Web.config中的定義。

<system.web> 
    <compilation debug="true" targetFramework="4.0" batch="true"> 
     <assemblies> 
      <add assembly="My.Web.Stuff" /> 
     </assemblies> 
    </compilation> 
    <pages> 
     <namespaces> 
      <add namespace="My.Web.Stuff.Extensions" /> 
     </namespaces> 
    </pages> 
</system.web> 

這是擴展方法的實現:

/// <summary> 
/// Extension methods on IEnumerable. 
/// </summary> 
public static class SelectListExtensions 
{ 
    /// <summary> 
    /// Converts the source sequence into an IEnumerable of SelectListItem 
    /// </summary> 
    /// <param name = "items">Source sequence</param> 
    /// <param name = "nameSelector">Lambda that specifies the name for the SelectList items</param> 
    /// <param name = "valueSelector">Lambda that specifies the value for the SelectList items</param> 
    /// <returns>IEnumerable of SelectListItem</returns> 
    public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> valueSelector, Func<TItem, string> nameSelector) 
    { 
     return items.ToSelectList(valueSelector, nameSelector, x => false); 
    } 

    /// <summary> 
    /// Converts the source sequence into an IEnumerable of SelectListItem 
    /// </summary> 
    /// <param name = "items">Source sequence</param> 
    /// <param name = "nameSelector">Lambda that specifies the name for the SelectList items</param> 
    /// <param name = "valueSelector">Lambda that specifies the value for the SelectList items</param> 
    /// <param name = "selectedItems">Those items that should be selected</param> 
    /// <returns>IEnumerable of SelectListItem</returns> 
    public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> valueSelector, Func<TItem, string> nameSelector, IEnumerable<TValue> selectedItems) 
    { 
     return items.ToSelectList(valueSelector, nameSelector, x => selectedItems != null && selectedItems.Contains(valueSelector(x))); 
    } 

    /// <summary> 
    /// Converts the source sequence into an IEnumerable of SelectListItem 
    /// </summary> 
    /// <param name = "items">Source sequence</param> 
    /// <param name = "nameSelector">Lambda that specifies the name for the SelectList items</param> 
    /// <param name = "valueSelector">Lambda that specifies the value for the SelectList items</param> 
    /// <param name = "selectedValueSelector">Lambda that specifies whether the item should be selected</param> 
    /// <returns>IEnumerable of SelectListItem</returns> 
    public static IEnumerable<SelectListItem> ToSelectList<TItem, TValue>(this IEnumerable<TItem> items, Func<TItem, TValue> valueSelector, Func<TItem, string> nameSelector, Func<TItem, bool> selectedValueSelector) 
    { 
     return from item in items 
       let value = valueSelector(item) 
       select new SelectListItem 
         { 
         Text = nameSelector(item), 
         Value = value.ToString(), 
         Selected = selectedValueSelector(item) 
         }; 
    } 
} 
+0

我喜歡它。將在明天的工作中使用它!代碼看起來合法,標記爲答案,謝謝! – Gromer