【问题标题】:MVC3 Conditionally disable Html.TextBoxFor()MVC3 有条件地禁用 Html.TextBoxFor()
【发布时间】:2012-02-23 13:25:38
【问题描述】:

我有一个 C# .Net 网络应用程序。在那个应用程序中,我需要根据谁登录到系统有条件地禁用Html.TextBoxFor 控件(也可以是Html.DropDownListFor 控件)。我尝试使用

 @Html.TextBoxFor(model => model.ProposalName, new { @ViewBag.IsDisabled })

@ViewBag.IsDisabled 在控制器中设置为 String.Empty"disabled"。但是,这会呈现为 IsDisabled='disabled'IsDisabled="",因此不会禁用控件。当我尝试时

@Html.TextBoxFor(model => model.ProposalName, new { @ViewBag.Disabled })

即使ViewBag.Disabled 不包含任何文本,该控件也始终处于禁用状态。如何有条件地禁用Html.TextBoxFor() 控件?

【问题讨论】:

    标签: asp.net-mvc-3 conditional html.textbox


    【解决方案1】:

    试试

    @Html.TextBoxFor(model => model.ProposalName, ViewBag.Disabled ? (object)new { disabled="disabled" } : new {})
    

    【讨论】:

    • @MikeTWebb ViewBag.Disabled 应该是一个布尔值。
    • 感谢,它对我的​​ mvc 项目很有用
    • 对象的类型对我很有帮助
    【解决方案2】:

    @epignosisx 发布的解决方案有效,但如果您想添加其他属性可能会出现问题,因为您必须将它添加到两个对象(带有disabled 的对象和现在为空的对象)。

    如果你有一些其他的 bool 属性,那就更糟了,因为你将有四个不同的对象,每个对象对应一个组合。

    这里最好的解决方案(使用更多代码)是为 HtmlHelper 构建一个扩展方法,以接收您的布尔属性作为参数。

    public static MvcHtmlString TextBoxDisabledFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool disabled, object htmlAttributes = null)
    {
        return TextBoxDisabledFor(htmlHelper, expression, disabled, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }
    
    public static MvcHtmlString TextBoxDisabledFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool disabled, IDictionary<string, object> htmlAttributes)
    {
        if (htmlAttributes == null)
            htmlAttributes = new Dictionary<string, object>();
        if (disabled)
            htmlAttributes["disabled"] = "disabled";
        return htmlHelper.TextBoxFor(expression, htmlAttributes);
    }
    

    Here there is another example

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,决定编写自己的 HtmlHelper 扩展方法。

      public static MvcHtmlString Disable(this MvcHtmlString helper, bool disabled)
          {
              if (helper == null)
                  throw new ArgumentNullException();
      
              if (disabled)
              {
                  string html = helper.ToString();
                  int startIndex = html.IndexOf('>');
      
                  html = html.Insert(startIndex, " disabled=\"disabled\"");
                  return MvcHtmlString.Create(html);
              }
      
              return helper;
          }
      

      这将接受一个布尔值来指示控件是否应该被禁用。它只是在字符串中遇到的第一个 &gt; 中附加 disabled="disabled"

      你可以像下面这样使用它。

      @Html.TextBoxFor(model =&gt; model.ProposalName).Disable(true)

      【讨论】:

        【解决方案4】:

        这是我使用的方法,它不需要扩展,也不会限制您只使用一个 HTML 属性。它假定您的模型中有一个名为“已禁用”的布尔属性,但您可以在其中放置您想要的任何内容,只要它对三元运算符的计算结果为布尔值:

        @Html.TextBoxFor(model => model.Whatever,
          new Dictionary<string, object>() {
            { "size", "5" },
            { "class", "someclasshere" },
            { model.Disabled ? "disabled" : "data-notdisabled", "disabled" }
          })
        

        标准快捷符号的限制是属性的名称不能是动态的。通过创建正确类型的字典,您可以使属性名称动态化,然后将该字典作为属性字典传递给文本框。当该字段不被禁用时,它会传递一个名为“data-notdisabled”的属性而不是一个名为“disabled”的属性,然后浏览器将忽略该属性。

        【讨论】:

        • 巧妙的想法有条件地更改属性名称而不是值,这仍然允许在 TextBoxFor 调用中内联。
        【解决方案5】:

        扩展@James 的答案,我编写了这个 HtmlHelper 扩展,如果 disabled 属性已经存在,则更新/删除它,如果不存在,则添加它:

        public static MvcHtmlString Disable(this MvcHtmlString helper, bool disabled) {
            string html = helper.ToString();
            var regex = new Regex("(disabled(?:=\".*\")?)");
            if (regex.IsMatch(html)) {
                html = regex.Replace(html, disabled ? "disabled=\"disabled\"" : "", 1);
            } else {
                regex = new Regex(@"(\/?>)");
                html = regex.Replace(html, disabled ? "disabled=\"disabled\"$1" : "$1", 1);
            }
            return MvcHtmlString.Create(html);
        }
        

        它还可以很好地使用自闭合标签(如&lt;input /&gt;)。

        用法同理:

        @Html.TextBoxFor(model => model.PropertyName).Disable(true)
        

        @Html.DropDownListFor()@Html.TextBoxFor() 上测试。

        【讨论】:

          【解决方案6】:

          对属性使用字典并有条件地添加禁用的属性。

              <div>
                  @{ 
                      var attribs = new Dictionary<String, object>
                          {
                              { "class", "form-control" }
                              ,{ "style",  "display:inline; width:100px;"}
                          };
          
                      if (Model.IsFieldDisabled)
                      {
                          attribs.Add("disabled", true);
                      }
                  }
          
                  @Html.TextBoxFor(m => m.MinValue, attribs)
                  to
                  @Html.TextBoxFor(m => m.MaxValue, attribs)
              </div>
          

          添加这个实际上只是为了在上面添加@ITFlyer 答案的更文字版本。他有条件地更改属性名称而不是值的方法很狡猾,并且仍然允许内联。然而,当我第一次看到它时,我错误地认为它不是有条件的,所以我认为更详细的版本仍然有价值,即使它在很大程度上只是重定向到那个答案。

          另一个好处是,一个单独的变量还允许对多个控件进行重用(在我的情况下我需要它

          【讨论】:

            猜你喜欢
            • 2012-02-18
            • 2011-10-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-28
            • 1970-01-01
            相关资源
            最近更新 更多