MVC3有条件地禁用Html.TextBoxFor()

时间:2012-01-31 20:03:30

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

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

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

其中@ViewBag.IsDisabled在Controller中设置为 String.Empty “disabled”。但是,这会呈现为IsDisabled='disabled'IsDisabled="",因此不会禁用该控件。我试过的时候

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

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

5 个答案:

答案 0 :(得分:54)

尝试

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

答案 1 :(得分:20)

@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

答案 2 :(得分:10)

我遇到了同样的问题,并决定编写自己的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;
    }

这将接受一个布尔值来指示是否应该禁用该控件。它只是将disabled="disabled"添加到字符串中出现的第一个>内。

您可以像下面一样使用它。

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

答案 3 :(得分:8)

这是我使用的方法,它不需要扩展,也不仅限于一个HTML属性。它假设你的模型中有一个名为“Disabled”的布尔属性,但你可以在那里放置任何你想要的东西,只要它为三元运算符求值为boolean:

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

标准快捷方式表示法的限制是属性的名称不能是动态的。通过创建正确类型的字典,您可以将属性名称设置为动态,然后将该字典作为属性字典传递到文本框。当不禁用该字段时,它会传递名为“data-notdisabled”的属性,而不是名为“disabled”的属性,然后浏览器将忽略该属性。

答案 4 :(得分:6)

扩展@ 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);
}

它也适用于自动关闭标签(如<input />)。

用法是一样的:

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

同时对@Html.DropDownListFor()@Html.TextBoxFor()进行了测试。