How to get the set/real value of the Visible property in Asp.Net
.net, asp.net, c#, web-controls
Solution
After digging around a bit, I have produced the following extension method that uses reflection to retrieve the value of the `Visible` flag for classes inheriting from `System.Web.UI.Control`:
public static bool LocalVisible(this Control control)
{
var flags = typeof (Control)
.GetField("flags", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(control);
return ! (bool) flags.GetType()
.GetProperty("Item", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(flags, new object[] {0x10});
}
It uses reflection to find the private field `flags` within the `Control` object. This field is declared with an internal type, so more reflection is needed to invoke the getter of its indexer property.
The extension method has been tested on the following markup:
<asp:Panel Visible="false" runat="server">
<asp:Literal ID="litA" runat="server" />
<asp:Literal ID="litB" Visible="true" runat="server" />
<asp:Literal ID="litC" Visible="false" runat="server" />
</asp:Panel>
<asp:Literal ID="litD" runat="server" />
<asp:Literal ID="litE" Visible="true" runat="server" />
<asp:Literal ID="litF" Visible="false" runat="server" />
Test results:
litA.LocalVisible() == true
litB.LocalVisible() == true
litC.LocalVisible() == false
litD.LocalVisible() == true
litE.LocalVisible() == true
litF.LocalVisible() == false
Problem
The Get of the Visible property of a control recursively looks up the tree to indicate if the control will be rendered or not. I need a way to see what the "local" visible value of a control is regardless of what its parent controls are set to. i.e. Whether it itself was set to true or false. I have seen this question, How to get the “real” value of the Visible property? which uses Reflection to obtain the local state, however, I have not been able to get this working for WebControls. It's also a rather dirty method of getting the value. I have come up with the following extension method. It works by removing the control from its parent, checking the property, then putting the control back where it found it. ``` public static bool LocalVisible(this Control control) { //Get a reference to the parent Control parent = control.Parent; //Find where in the parent the control is. int index = parent.Controls.IndexOf(control); //Remove the control from the parent. parent.Controls.Remove(control); //Store the visible state of the control now it has no parent. bool visible = control.Visible; //Add the control back where it was in the parent. parent.Controls.AddAt(index, control); //Return the stored visible value. return visible; } ``` Is this an acceptable way of doing this? It works fine and I haven't come across any performance issues. It just seems extremely dirty and I have no doubt there could be instances in which it might fail (for example, when actually rendering). If anyone has any thoughts on this solution or better still a nicer way of finding the value then that would be great.