ASP.NET 3.5: как запретить дочерние элементы управления beind, когда родительский элемент управления отключен? - PullRequest
1 голос
/ 11 августа 2011

Возьмем этот простой пример, например:

<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 ]

1 голос
/ 11 августа 2011

Это сделано специально, и для достижения эффекта, который вы ищете, вам нужно использовать другой подход. Я бы предложил рекурсивно перебирать дочерние элементы управления и использовать некоторую логику, чтобы определить, какие элементы управления отключены, а какие нет.

0 голосов
/ 12 августа 2011

Это связано с тем, что у элементов управления есть дополнительное внутреннее свойство IsEnabled, которое возвращается как False, если для элемента управления или любого из элементов управления в родительском дереве значение Enabled установлено на False.Во время рендеринга TextBox добавляет атрибут disabled, если это свойство IsEnabled имеет значение False.

Вы можете создавать свои собственные пользовательские элементы управления, наследуя их от элементов управления Panel и TextBox, и добавлять свои собственные свойства и логику.Что-то вроде того, что у меня ниже, должно работать.

Кроме того, я бы не рекомендовал отображать отключенный атрибут на панели, который отображается как div.Атрибут disabled не является стандартным атрибутом html для div, и браузеры отображают содержимое непоследовательно.Например, 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;
    }
}
0 голосов
/ 11 августа 2011

вы можете сделать это на стороне клиента, используя JavaScript.

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

for (var i = 0; i < controls.length; i++)
    controls[i].disabled = true; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...