动态设置禁用HTML属性为TextBoxFor的HtmlHelper(Dynamically set

2019-07-29 01:40发布

我想动态设置disabled该属性TextBoxFor的HtmlHelper

@Html.TextBoxFor(model => model.Street, 
                 new
                 {
                    @class = "", 
                    disabled = (Model.StageID==(int)MyEnum.Sth) ? "disabled" : "" 
                 })

但即使是disabled=""这是一样的disabled="disabled" 。 如何解决这件事?

Answer 1:

我有大约一个月同样的问题以前,我完成了使用此扩展方法吧

public static class AttributesExtensions
{
    public static RouteValueDictionary DisabledIf(
        this object htmlAttributes, 
        bool disabled
    )
    {
        var attributes = new RouteValueDictionary(htmlAttributes);
        if (disabled)
        {
            attributes["disabled"] = "disabled";
        }
        return attributes;
    }
}

在这之后,你可以使用它像这样

@Html.TextBoxFor(
    model => model.Street, 
    new { @class = "" }.DisabledIf(Model.StageID==(int)MyEnum.Sth)
)

编辑 (后保罗的评论 ):

使用的data-xxx HTML属性可以通过使用的构造被开采System.Web.Routing.RouteValueDictionary类,因为下划线不会被自动转换为负号。

使用方法System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes代替:将解决这个问题。

更新后的代码 (仅扩展方法体)

var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (disabled)
{
    attributes["disabled"] = "disabled";
}
return attributes;


Answer 2:

用下面的扩展方法产生类似的结果,但是这也许是更脆弱:

@Html.TextBoxFor(
     model => model.Street, 
     new { @class = "form-control" }
).DisabledIf(Model.IsReadOnly)

延期:

using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace xxx.HtmlHelpers
{
    public static class MvcHtmlStringExtensions
    {

        private static readonly Regex OpeningTagPattern;

        static MvcHtmlStringExtensions()
        {
            OpeningTagPattern = new Regex("<[a-zA-Z]*");
        }

        public static MvcHtmlString DisabledIf(this MvcHtmlString controlHtml, bool isDisabled)
        {
            if (!isDisabled) return controlHtml;
            return
                new MvcHtmlString(OpeningTagPattern.Replace(controlHtml.ToString(),
                    x => string.Format("{0} disabled=\"disabled\"", x.Groups[0])));
        }

    }
}


Answer 3:

也许你的关卡ID不获取设置

@{ 
    if(Model.StageID != null &&   Model.StageID > 0)
    {
        @Html.TextBoxFor(model => model.Street, 
             new
             {
                @class = "", 
                disabled = (Model.StageID==(int)MyEnum.Sth) ? "disabled" : "" 
             })
    }else{

        @Html.TextBoxFor(model => model.Street, 
             new
             {
                @class = ""
             })
    }
}


Answer 4:

实际上,我们只是遇到了同样的问题。 我们最终实现的扩展方法具有重载参数,它接受一个布尔值,指示我们是否要禁用控制。 我们只是在适当的时候添加“已禁用”属性,并让内置的HtmlHelper处理繁重。

扩展的类和方法:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
public static class OurHtmlHelpers
{
    public const string DisabledAttribute = "disabled";

    public static MvcHtmlString TextBoxFor<TModel, TProp>(this HtmlHelper<TModel> htmlHelper, 
                                                            Expression<Func<TModel, TProp>> expression, 
                                                            object htmlAttributes, 
                                                            bool canEdit)
    {
        var htmlAttributeDictionary = SetDisabledAttribute(htmlAttributes, canEdit);

        return htmlHelper.TextBoxFor(expression, htmlAttributeDictionary);
    }        

    private static RouteValueDictionary SetDisabledAttribute(object htmlAttributes, bool canEdit)
    {
        var htmlAttributeDictionary = new RouteValueDictionary(htmlAttributes);

        if (!canEdit)
        {
            htmlAttributeDictionary.Add(DisabledAttribute, DisabledAttribute);
        }

        return htmlAttributeDictionary;
    }
}

然后你只需要引用新的类并调用@Html.TextBoxFor(m => m.SomeValue, new { @class = "someClass" }, <Your bool value>)

值得一提的是,你必须确定这些扩展对于任何TextBoxFor的重载你想使用,但它似乎是一个合理的权衡。 您还可以利用最适合你想要的功能添加到其他HtmlHelpers相同的代码。



文章来源: Dynamically set the disabled html attribute for TextBoxFor HtmlHelper