2010-01-18 71 views
15

如何更改此DropDownList聲明,以便禁用屬性有條件啓用/禁用?有條件地禁用Html.DropDownList

<%= Html.DropDownList("Quantity", new SelectList(...), new{@disabled="disabled"} %> 

非工作實施例:

<%= Html.DropDownList("Quantity", new SelectList(...), new{@disabled=Model.CanEdit?"false":"disabled"} %> 

P.S.添加如果條件環繞整個語句是不希望的做法:)

編輯:基於從我想出了下面的擴展的另一個問題this擴展方法:

public static IDictionary<string, object> Disabled (this object obj, bool disabled) 
{ 
    return disabled ? obj.AddProperty ("disabled", "disabled") : obj.ToDictionary(); 
} 

然後可以作爲

<%= Html.DropDownList("Quantity", new SelectList(...), new{id="quantity"}.Disabled(Model.CanEdit) %> 
+0

您好,我想禁用/啓用僅基於價值的具體頁面下拉,我將其通過模型。我嘗試將true/false傳遞給殘疾人,但它不工作。可以幫助你在這 – ravithejag 2014-09-12 05:58:44

回答

19

請不要寫意大利麪代碼。 HTML輔助在那裏爲這個目的:

public static MvcHtmlString DropDownList(this HtmlHelper html, string name, SelectList values, bool canEdit) 
{ 
    if (canEdit) 
    { 
     return html.DropDownList(name, values); 
    } 
    return html.DropDownList(name, values, new { disabled = "disabled" }); 
} 

然後:

<%= Html.DropDownList("Quantity", new SelectList(...), Model.CanEdit) %> 

或者,也許你能想出一些更好的(如果模型中包含的選項):

<%= Html.DropDownList("Quantity", Model) %> 

您還將獲得更多單元可測試代碼的獎勵。

+0

如何使用助手使單元測試您的視圖更容易? – 2010-01-18 22:14:18

+1

由於WebForms引擎的性質,您無法單元測試視圖。你可以通過測試擴展方法。這樣你的視圖將不再包含值得進行單元測試的條件邏輯。通過測試擴展方法,確保使用它的所有視圖都會按照您的期望行事,並具有確切的標記,具體取決於模型上的CanEdit屬性。 – 2010-01-18 22:54:36

+0

如果我需要使用此簽名的助手方法,此代碼將如何顯示? '公共靜態字符串DropDownList的(這個HTML的HtmlHelper,字符串名稱,值的SelectList,對象htmlAttributes,布爾canEdit)' – 2011-03-12 12:07:05

-2

我不知道ASP.NET提供了一個更簡潔的特殊情況下的辦法,但想必你可以這樣做:

<%= Html.DropDownList("Quantity", new SelectList(...), Model.CanEdit? new{@class="quantity"} : new{@class="quantity", @disabled:"disabled"}) %> 
+2

不,你不能那樣做。您會收到編譯時錯誤:「無法確定條件表達式的類型,因爲'AnonymousType#1'和'AnonymousType#2'之間沒有隱式轉換」「 – 2012-09-11 11:55:47

+0

不起作用請刪除此答案 – 2013-02-08 11:31:38

+0

您需要添加將其轉換爲anonymousTypes'作爲對象',而不是它的工作 – 2016-06-29 12:35:01

5

一個選項是創建一個自定義版本的Html.DropDownList,它需要一個額外的參數並做你想做的事......但是接下來你將不得不爲每一個輔助類型創建一個新的 - TextBoxFor,TextAreaFor,CheckBoxFor,等等...而你仍然必須弄清楚如何使它的工作膽量。

相反,我選擇了創建一個Html Helper來替換普通的匿名HtmlAttributes對象,因爲它將與所有使用HtmlAttributes的Helper兼容,而無需任何特殊工作。此解決方案還允許您通過其他屬性,如類,名稱或任何您想要的。它不會將您鎖定爲僅禁用。

我創建了以下幫助器 - 它需要一個布爾值和一個匿名對象。如果禁用爲true,則會將禁用屬性添加到匿名對象(實際上是一個字典),其值爲「disabled」,否則它不會添加屬性。

public static RouteValueDictionary ConditionalDisable(
    bool disabled, 
    object htmlAttributes = null) 
{ 
    var dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 

    if (disabled) 
     dictionary.Add("disabled", "disabled"); 

    return dictionary; 
} 


行動它的一個例子:

@Html.TextBoxFor(m => m.SomeProperty,  
    HtmlHelpers.ConditionalDisable(true, new { @class = "someClass")) 


一個巨大的優勢,這種方法對我來說,它幾乎適用所有的MVC HtmlHelpers的,因爲它們都有重載接受一個RouteValueDictionary而不是一個匿名對象。

注意事項
HtmlHelper.AnonymousObjectToHtmlAttributes()使用一些花哨的代碼忍者工作,把事情做好。我不完全確定它的性能如何......但對於我使用它來說已經足夠了。你的旅費可能會改變。

我不特別喜歡它的名字 - 但我不能拿出更好的東西。重命名很簡單。

我也不喜歡使用語法 - 但我再也找不到更好的東西。改變應該不難。在object上的擴展方法是一個想法......你最終與new { @class = "someClass" }.ConditionalDisable(true),但如果你只想要禁用屬性,並沒有任何額外的添加你最終得到像new {}.ConditionalDisable(true);一樣的東西,你也最終顯示所有對象的擴展方法......這可能是不可取的。

+0

這是唯一的答案,考慮可能性傳遞更多的htmlAttributes比一個,併爲所有HtmlHelpers工作。大拇指。 – 2016-06-29 12:42:00

22

沒有必要添加輔助方法,你可以用

<%= Html.DropDownList("Quantity", new SelectList(...), IsEditable == true ? new { @disabled = "disabled" } as object : new {} as object %> 

如果你刪除as object條目這不會因爲默認情況下new {}工作是在運行時編譯一個動態對象,因此兩個可能的對象必須具有相同的屬性。但是Html屬性參數實際上只是一個對象,所以這些動態可以被轉換爲對象來解決這個問題。

該解決方案甚至可以讓你使用多個HTML屬性,其中一個是可選的,另一種是沒有的,即class='whatever'不可選的,但disabled是那麼你把class='whatever'在兩個對象,但可選的一個僅在第一。 Dimitrov的答案不支持禁用以外的任何自定義屬性。

+6

+1這應該被標記爲最佳答案 – 2014-01-08 07:37:15

0

強類型verison:

public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> html, 
                    Expression<Func<TModel, TProperty>> expression, 
                    IEnumerable<SelectListItem> selectList, 
                    string optionText, bool canEdit) 
    { 
     if (canEdit) 
     { 
      return html.DropDownListFor(expression, selectList, optionText); 
     } 
     return html.DropDownListFor(expression, selectList, optionText, new { disabled = "disabled" }); 
    } 
2
@bool IsEditable=true; 

@if (IsEditable) 
{ 
    Html.DropDownListFor(m => m, selectList); 
} 
else 
{ 
    Html.DropDownListFor(m => m, selectList, new { disabled = "disabled" }) 
} 
相關問題