2010-01-18 70 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" }) 
} 
相关问题