示例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,我正在查询第0行中具体的具体TextBox。)
背景: TextBox是一个智能控件:It only saves its Text property in the ViewState if it's invisible.这是有道理的:如果TextBox可见,它将呈现为HTML <input>
控件及其当前{{1值在回发时提交 - 无需通过ViewState再次提交。当然,如果TextBox不可见,则不会呈现它,因此,对Text
属性的任何更改都将丢失。
现在,示例2给我们带来了一些麻烦。 Text
认为它正在呈现(根据IL间谍,它在textbox
中检查自己的Visible
属性),因此它不使用ViewState和{{1}的所有更改代码中的完成丢失了。我现在想知道这是不是错误。
相关问题: How to get the set/real value of the Visible property in Asp.Net.
编辑:我已就此创建了Microsoft Connect Bug报告:
答案 0 :(得分:4)
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
属性为false(在运行时且如果有),它将始终返回Visible
父指定)。因此,为了回答标题中提到的问题,Visible
属性在任何时间点都不会自动设置为false
,只是在访问时才进行评估。如果GridView
TextBox.Visible
返回true
,则TextBox
的父控件不是TemplateColumn
,或者至少是父项的Visible
属性设置为false。
修改强>
因此,在问题中使用示例网格,如果您向上走控制链,您将看到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
属性正在按预期工作。