2011-07-08 87 views
3

我試着去創建一個IList的下拉列表與語法如下:C#MVC HTML輔助+表情+刪除uglyness

@Html.DropDowntListFor(Model.VisitingAddresses, vistingAddress => vistingAddress.Id, vistingAddress => vistingAddress.Name) 

這適用於下面的代碼:

public static IHtmlString DropDowntListFor 
     <TModel>(this HtmlHelper htmlHelper, IList<TModel> list, Expression<Func<TModel, string>> value, Expression<Func<TModel, string>> text) 
    { 
     var dropdownName = value.Parameters.First().Name; 

     var selectedListItem = new List<SelectListItem>(); 

     var values = list.AsQueryable().Select(value).ToList(); 
     var texts = list.AsQueryable().Select(text).ToList(); 

     int i; 
     for (i = 0; i < values.Count; i++) 
     { 
      selectedListItem.Add(new SelectListItem 
            { 
             Value = values[i], 
             Text = texts[i] 
            }); 
     } 

     return htmlHelper.DropDownList(dropdownName, selectedListItem); 
    } 

但你可以看到上面的代碼(在htmlhelper中)真的很難看,有沒有人知道在html助手中更漂亮的方式(在代碼中)?

在此先感謝。

+0

你爲什麼覺得這很醜? –

+0

菲利普感謝您的回覆,你看過我的代碼嗎?我硬編碼下拉列表選擇第一個與LINQ然後名稱也列表.AsQueryable()然後一個選擇,for循環這一切應該不會討厭與一些漂亮的表達? – daanl

+0

當Jon發佈他的答案時,我明白你的意思。我只是認爲你的代碼是可讀的,所以它不醜。也許它沒有優化,但並不難看。 –

回答

4

你是否像這樣?

public static IHtmlString DropDowntListFor<TModel> 
    (this HtmlHelper htmlHelper, IList<TModel> list, 
    Expression<Func<TModel, string>> valueSelector, 
    Expression<Func<TModel, string>> textSelector) 
{ 
    var dropdownName = valueSelector.Parameters.First().Name; 

    Func<TModel, string> compiledValueSelector = valueSelector.Compile(); 
    Func<TModel, string> compiledTextSelector = textSelector.Compile(); 

    var selectedListItem = list.Select(x => new SelectListItem { 
              Value = compiledValueSelector(x), 
              Text = compiledTextSelector(x) }) 
           .ToList(); 

    return htmlHelper.DropDownList(dropdownName, selectedListItem); 
} 

請注意,如果您不需要文本選擇作爲表達式樹,你可以稍微進一步簡化它:

public static IHtmlString DropDowntListFor<TModel> 
    (this HtmlHelper htmlHelper, IList<TModel> list, 
    Expression<Func<TModel, string>> valueSelectorExpression, 
    Func<TModel, string> textSelector) 
{ 
    var dropdownName = valueSelector.Parameters.First().Name; 

    var valueSelector = valueSelectorExpression.Compile(); 

    var selectedListItem = list.Select(x => new SelectListItem { 
              Value = valueSelector(x), 
              Text = textSelector(x) }) 
           .ToList(); 

    return htmlHelper.DropDownList(dropdownName, selectedListItem); 
} 
+0

事實上,這將使它減少潰敗,謝謝! – daanl

0

如何如下:

@Html.DropDowntListForVisitingAddress(x => x.Id, x => x.Name) 

和那麼因爲您的視圖已經被強制鍵入某個模型,所以HtmlHelper已經是強類型了=>使用它來獲取模型:

public static IHtmlString DropDowntListForVisitingAddress(
    this HtmlHelper<MyViewModel> html, 
    Func<VisitingAddress, string> value, 
    Func<VisitingAddress, string> text 
) 
{ 
    MyViewModel model = html.ViewData.Model; 
    var values = model.VisitingAddresses.Select(x => new SelectListItem 
    { 
     Value = value(x), 
     Text = text(x) 
    }); 
    var selectList = new SelectList(values, "Value", "Text"); 
    return html.DropDownListFor(
     x => x.SelectedAddress, 
     selectList 
    ); 
} 
+1

我還有其他20款車型嗎? – daanl

+0

@daanl,讓他們實現一個通用的接口或基本視圖模型。我希望你不要在你的另外20個視圖模型中重複這個邏輯。 –

+1

Im不會在我的視圖模型中實現一個Html幫助器 – daanl