asp.net:子控件的Visible属性什么时候自动设置?
示例 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 至少有一行)。
问题:这种不一致的行为是设计造成的吗?在这两种情况下,文本框都不会呈现,因为某些父元素不可见。
(当然,在第二种情况下,文本框位于模板内,但我没有查询模板定义中的抽象文本框,而是查询第 0 行中的具体具体文本框。)
背景: TextBox 是一个智能控件: 它仅在不可见时将其 Text 属性保存在 ViewState 中。 这是有道理的:如果 TextBox 可见,则将其呈现为 HTML 控件及其当前
Text
值在回发时提交 - 无需通过 ViewState 再次提交。当然,如果 TextBox 不可见,则不会呈现它,因此对 Text
属性的任何更改都将丢失。
现在,示例 2 给我们带来了一些麻烦。 textbox
认为它正在被渲染(根据 IL 间谍,它在 TextBox.SaveTextViewState
中检查自己的 Visible
属性),因此它没有使用 ViewState 时,在代码中对 textbox.Text
所做的所有更改都会丢失。我现在想知道这是否是错误。
相关问题: 如何获取 Asp.Net 中 Visible 属性的设置/实际值。
编辑: 我已就此创建了 Microsoft Connect 错误报告:
Example 1:
<asp:Panel Visible="false" runat="server">
<asp:TextBox ID="textbox" runat="server" />
</asp:Panel>
Here, textbox.Visible
returns false
in code (even though TextBox.Visible
was not set explicitly; it seem to "inherit" the property from its invisible parent).
Example 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>
Here, ((TextBox)grid.Items[0].FindControl("textbox")).Visible
returns true
(under the assumption that the DataGrid has at least one row).
Question: Is this inconsistent behaviour by design? In both cases, the TextBox is not rendered because some parent element is invisible.
(Granted, in the second case the textbox is inside a template, but I'm not querying an abstract TextBox in the template definition, I'm querying the specific, concrete TextBox in row number 0.)
Background: TextBox is a smart control: It only saves its Text property in the ViewState if it's invisible. That makes sense: If the TextBox is visible, it's rendered as a HTML <input>
control and its current Text
value is submitted on a postback - no need to submit it again via the ViewState. Of course, if the TextBox is invisible, it is not rendered, and, thus, any changes to the Text
property would be lost.
Now, Example 2 is giving us some trouble. textbox
thinks that it's being rendered (according to IL spy, it checks its own Visible
property in TextBox.SaveTextViewState
), so it doesn't use the ViewState and all changes to textbox.Text
done in code are lost. I'm now wondering whether this is bug or not.
Related question: How to get the set/real value of the Visible property in Asp.Net.
EDIT: I've created a Microsoft Connect Bug Report on this:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
TextBox
和Panel
都继承自WebControl
,而WebControl
又继承自Control
。Control
对Visible
属性有以下定义:由于
Visible
不是直接在TextBox
上实现的,因此它始终会如果父级的Visible
属性为 false(在运行时且指定了父级),则返回false
。因此,为了回答标题中提出的问题,Visible
属性在任何时间点都不会自动设置为false
,它只是在访问时进行评估。在GridView
中TextBox.Visible
返回true
的情况下,按理说TextBox
的父控件code> 不是TemplateColumn
,或者至少父级没有将其Visible
属性设置为 false。编辑
因此,使用问题中的示例网格,如果您向上遍历控件链,您将看到
TextBox
的所有父控件都是Visible
。我使用了下面的代码,输出如下:代码:
在我看来,
DataGrid
和Visisble
属性按预期工作。TextBox
andPanel
both inherit fromWebControl
, which inherits fromControl
.Control
has the following definition for theVisible
property:Since
Visible
is not implemented directly onTextBox
, it will always returnfalse
if theVisible
property of the parent is false (at runtime and if there is a parent specified). So to answer the question asked in the title, theVisible
property is not automatically set tofalse
at any point in time, it's just evaluated when it is accessed. In the case of theGridView
whereTextBox.Visible
returnstrue
, it stands to reason that the parent control of theTextBox
is not theTemplateColumn
, or at least the parent does not have itsVisible
property set to false.EDIT
So, using your example grid in the question, if you walk the chain of controls up, you'll see that all of the parent controls for the
TextBox
areVisible
. I used the code below, and here's the output:Code:
It seems to me that the
DataGrid
and theVisisble
properties are working as expected.