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: