代码之家  ›  专栏  ›  技术社区  ›  Todd Smith Brandon

有条件地禁用html.dropdownlist

  •  17
  • Todd Smith Brandon  · 技术社区  · 14 年前

    如何更改此DropDownList声明,使禁用的属性有条件地启用/禁用?

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

    非工作示例:

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

    P.S.在整个语句周围添加if条件不是所需的方法:)

    编辑: 基于 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) %>
    
    7 回复  |  直到 6 年前
        1
  •  19
  •   Leniel Maccaferri    12 年前

    请不要写意粉代码。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) %>
    

    您还将获得更多单元可测试代码的奖励。

        2
  •  26
  •   AlexB borjafp    7 年前

    不需要添加助手方法,只需使用

    <%= 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的答案不支持除disabled以外的任何自定义属性。

        3
  •  9
  •   Mir    11 年前

    一个选项是创建一个自定义的html.dropdownlist版本,该版本使用一个额外的参数并执行您想要的操作…但是,您必须为每种类型的助手创建一个新的助手-textbox for、textbarefor、checkboxfor等…你还得想办法让它发挥作用。

    我选择创建一个HTML助手来替换普通的匿名htmlattributes对象,因为这样它就可以与所有使用htmlattributes的助手兼容,而不需要任何特殊的工作。此解决方案还允许您传递其他属性,如类、名称或任何您想要的属性。它不会把你锁定为只有残疾人。

    我创建了以下助手-它使用一个布尔值和一个匿名对象。如果disabled为true,则将disabled属性添加到值为“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 HTMLHelper一起工作,因为它们都具有接受RouteValueDictionary而不是匿名对象的重载。

    告诫 :
    htmlHelper.AnonymousObjectTohtmlattributes()使用一些花哨的代码忍者工作来完成任务。我不完全确定它的性能…但我用它做什么已经足够了。您的里程可能会有所不同。

    我不太喜欢它的名字,但我想不出更好的名字。重命名很容易。

    我也不喜欢使用语法-但我还是想不出更好的方法。这不应该很难改变。上的扩展方法 object 有一种想法…你最终会 new { @class = "someClass" }.ConditionalDisable(true) 但是,如果你只想要disable属性,并且没有任何额外的添加内容,那么你最终会得到一些恶心的东西,比如 new {}.ConditionalDisable(true); 最后你还会得到一个扩展方法,它可以显示所有对象…这可能是不可取的。

        4
  •  2
  •   Horizon_Net    9 年前
    @bool IsEditable=true;
    
    @if (IsEditable)
    {
        Html.DropDownListFor(m => m, selectList);
    }
    else
    {
        Html.DropDownListFor(m => m, selectList, new { disabled = "disabled" })
    }
    
        5
  •  0
  •   proggrock    10 年前

    强类型版本:

     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" });
        }
    
        6
  •  0
  •   Antonio Bakula    6 年前

    为了完整起见,这里有一个保存所有参数的函数,它会将选择值发布到服务器:

    public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes, bool enabled)
    {
      if (enabled)
      {
        return SelectExtensions.DropDownListFor<TModel, TProperty>(html, expression, selectList, htmlAttributes);
      }
    
      var htmlAttributesAsDict = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
      htmlAttributesAsDict.Add("disabled", "disabled");
      string selectClientId = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
      htmlAttributesAsDict.Add("id", selectClientId + "_disabled");
    
      var hiddenFieldMarkup = html.HiddenFor<TModel, TProperty>(expression);
      var selectMarkup = SelectExtensions.DropDownListFor<TModel, TProperty>(html, expression, selectList, htmlAttributesAsDict);
      return MvcHtmlString.Create(selectMarkup.ToString() + Environment.NewLine + hiddenFieldMarkup.ToString());
    }
    

    使用示例,禁用下拉列表如果列表中只有一个项目,则该值仍将以正确的客户端ID发布到服务器:

    @Html.DropDownListFor(m => m.SomeValue, Model.SomeList, new { @class = "some-class" }, Model.SomeList > 1)
    
        7
  •  -2
  •   bobince    14 年前

    我不知道ASP.NET是否提供了更简洁的特殊情况方法,但可以这样做:

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