asp.net: Когда автоматически устанавливается свойство Visible дочерних элементов управления? - PullRequest
2 голосов
/ 13 июля 2011

Пример 1:

<asp:Panel Visible="false" runat="server">
    <asp:TextBox ID="textbox" runat="server" />
</asp:Panel>

Здесь textbox.Visible возвращает false в коде (даже если TextBox.Visible не было задано явно; кажется, что оно «наследует»свойство от его невидимого родителя).

Пример 2:

<asp:DataGrid ID="grid" runat="server" AutoGenerateColumns="false">
    <Columns>
        <asp:TemplateColumn Visible="False">
            <ItemTemplate>
                <asp:TextBox ID="textbox" runat="server" />
            </ItemTemplate>
        </asp:TemplateColumn>
    </Columns>
    ...
</asp:DataGrid>

Здесь ((TextBox)grid.Items[0].FindControl("textbox")).Visible возвращает true (при условии, что DataGrid имеет по крайней мереодин ряд).


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

(Конечно, во втором случае текстовое поле находится внутри шаблона, но я не запрашиваю абстрактный TextBox в определении шаблона,Я запрашиваю конкретный конкретный TextBox в строке номер 0.)

Фон: TextBox - это интеллектуальный элемент управления: Он сохраняет свое свойство Text в ViewState, только если он невидим. Это имеет смысл: если TextBox виден, он отображается как элемент управления HTML <input>, а его текущее значение Text отправляется при обратной передаче - нет необходимости повторной отправки через ViewState.Конечно, если TextBox невидим, он не отображается, и, следовательно, любые изменения в свойстве Text будут потеряны.

Теперь пример 2 доставляет нам некоторые проблемы.textbox считает, что он визуализируется (согласно IL-шпиону, он проверяет свое собственное свойство Visible в TextBox.SaveTextViewState), поэтому он не использует ViewState и все изменения в textbox.Text, сделанные в коде, теряются.Теперь мне интересно, является ли это ошибкой или нет.


Смежный вопрос: Как получить заданное / реальное значение свойства Visible в Asp.Net.


РЕДАКТИРОВАТЬ: Я создал отчет об ошибках Microsoft Connect по этому вопросу:

1 Ответ

4 голосов
/ 13 июля 2011

TextBox и Panel оба наследуются от WebControl, который наследуется от Control.Control имеет следующее определение для свойства Visible:

public virtual bool Visible
{
    get
    {
        return !this.flags[16] &&
               (this._parent == null || this.DesignMode || this._parent.Visible);
    }
    set
    {
        if (this.flags[2])
        {
            bool flag = !this.flags[16];
            if (flag != value)
            {
                this.flags.Set(32);
            }
        }
        if (!value)
        {
            this.flags.Set(16);
            return;
        }
        this.flags.Clear(16);
    }
}

Поскольку Visible не реализован непосредственно в TextBox, он всегда вернет false, если свойство Visibleparent является ложным (во время выполнения и если указан родитель).Таким образом, чтобы ответить на вопрос, заданный в заголовке, свойство Visible не устанавливается автоматически на false в любой момент времени, оно просто оценивается при обращении к нему.В случае GridView, где TextBox.Visible возвращает true, очевидно, что родительский элемент управления TextBox не является TemplateColumn или, по крайней мере, родитель не имеет своего свойства Visibleустановлено в false.

EDIT Итак, используя примерную сетку в вопросе, если вы поднимите цепочку элементов управления вверх, вы увидите, что все родительские элементы управления для TextBox равны Visible.Я использовал приведенный ниже код, и вот что получилось:

TextBox (ClientID = grid_textbox_0, Visible = True)
TableCell (ClientID = grid_ctl00_0, Visible = True)
DataGridItem (ClientID = grid, Visible = True)
ChildTable (ClientID = grid_ctl00, Visible = True)
DataGrid (ClientID = grid, Visible = True)
HtmlForm (ClientID = form1, Visible = True)

Код:

protected void btnSubmit_Click(object sender, EventArgs e)
{
    var control = grid.Items[0].FindControl("textbox");
    while(control != this && control != null)
    {
        Response.Write(string.Format("{0} (ClientID = {1}, Visible = {2})",
            control.GetType().Name, control.ClientID, control.Visible));
        Response.Write("<br />");
        control = control.Parent;
    }
}

Мне кажется, что свойства DataGrid и Visisble работают как положено.

...