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:
TextBoxandPanelboth inherit fromWebControl, which inherits fromControl.Controlhas the following definition for theVisibleproperty:Since
Visibleis not implemented directly onTextBox, it will always returnfalseif theVisibleproperty of the parent is false (at runtime and if there is a parent specified). So to answer the question asked in the title, theVisibleproperty is not automatically set tofalseat any point in time, it’s just evaluated when it is accessed. In the case of theGridViewwhereTextBox.Visiblereturnstrue, it stands to reason that the parent control of theTextBoxis not theTemplateColumn, or at least the parent does not have itsVisibleproperty 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
TextBoxareVisible. I used the code below, and here’s the output:Code:
It seems to me that the
DataGridand theVisisbleproperties are working as expected.