ASP.NET 3.5:如何在禁用父控件时禁用beind的子控件?

时间:2011-08-11 15:36:52

标签: asp.net controls

以这个简单的例子为例:

<asp:Panel ID="pnlTest" runat="server">
    <asp:TextBox ID="txPanelText" Text="Text" runat="server" />
</asp:Panel>

现在,在代码隐藏中,执行此操作:

pnlTest.Enabled = false;
txPanelText.Enabled = true;

为什么禁用面板也会禁用其中的文本框?此外,为什么明确启用文本框没有效果?

这显然与ASP.NET框架有关。有什么办法可以避免这种情况吗?

注意:这不是我在我的应用程序中使用的实际代码。这只是一个示例,说明如何禁用控件也会递归地禁用其中的所有子控件。

3 个答案:

答案 0 :(得分:1)

这是设计上的,要达到你想要的效果,你需要使用不同的方法。我建议递归迭代子控件并使用一些逻辑来确定哪些控件被禁用,哪些不被禁用。

答案 1 :(得分:0)

您可以使用javascript在客户端执行此操作。

var controls = document.getElementById("<%=pnlTest.ClientID%>").getElementsByTagName("input");

for (var i = 0; i < controls.length; i++)
    controls[i].disabled = true; 

答案 2 :(得分:0)

这是因为控件有一个名为IsEnabled的附加内部属性,如果父树中的控件或任何控件的Enabled设置为False,则返回为False。在渲染过程中,如果此IsEnabled属性为False,则TextBox会添加disabled属性。

您可以通过继承Panel和TextBox控件来创建自己的自定义控件,并添加自己的属性和逻辑。像我下面的东西应该工作。

另外,我不建议在Panel上渲染disabled属性,它会呈现为div。 disabled属性不是div的标准html属性,浏览器会不一致地呈现内容。例如,IE 9调暗内部文本框(如果文本框没有自己的禁用属性)但仍然可以修改文本框值。 Firefox忽略标记并将文本框渲染为正常。

public class TextBox : System.Web.UI.WebControls.TextBox, IDisabled
{

    public System.Nullable<bool> Disabled
    {
        get { return (System.Nullable<bool>)ViewState["Disabled"]; }
        set { ViewState["Disabled"] = value; }
    }

    public override bool Enabled
    {
        get
        {
            if (this.Disabled.HasValue)
            {
                return !this.Disabled.Value;
            }
            else
            {
                return true;
            }
        }
        set { this.Disabled = !value; }
    }

    protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
    {
        base.AddAttributesToRender(writer);

        if (Utilities.RenderDisabled(this))
        {
            writer.AddAttribute(System.Web.UI.HtmlTextWriterAttribute.Disabled, "disabled");
        }
    }

}

public class Panel : System.Web.UI.WebControls.Panel, IDisabled
{

    public System.Nullable<bool> Disabled
    {
        get { return (System.Nullable<bool>)ViewState["Disabled"]; }
        set { ViewState["Disabled"] = value; }
    }

    public override bool Enabled
    {
        get { return true; }
        set { this.Disabled = !value; }
    }

}

public interface IDisabled
{
    System.Nullable<bool> Disabled { get; set; }
    bool Enabled { get; set; }
}

public sealed class Utilities
{
    public static bool RenderDisabled(IDisabled control)
    {
        return (control.Disabled.HasValue && control.Disabled.Value) || (!control.Disabled.HasValue && IsParentDisabled(control));
    }

    public static bool IsParentDisabled(IDisabled control)
    {
        System.Web.UI.Control current = ((System.Web.UI.Control)control).Parent;
        IDisabled currentDisabled = default(IDisabled);
        while (current != null)
        {
            currentDisabled = current as IDisabled;
            if (currentDisabled != null && currentDisabled.Disabled.HasValue)
            {
                return currentDisabled.Disabled.Value;
            }
            current = current.Parent;
        }

        return false;
    }
}