Tuesday, June 12, 2007

One of the other days I encountered a strange problem. I was unable to set the Visible property of one of built in ASP.NET controls to true. I had verified that it is indeed true that I'm passing as a new value for the property. I had even used the Watch and Immediate Windows to set that value - nothing worked. I had decided to see what is going on and so I looked at the source code of the Control's Visible property...

What I have discovered is that the Visible property is in fact a recursive property! What does it mean? In short, the Visible property will only be true if the Parent's Visible property is true which in turn will be true if... and so on, up to the top of the control hierarchy. No a bad idea after if you think about it.

This feature obviously has some impact on how everything in ASP.NET works. As an example take a look at the following code:

Control parent = new Control();
Control child = new Control();
child.Visible = false;
Response.Write(child.Visible + "<br />");
child.Visible = true;
Response.Write(child.Visible + "<br />");
parent.Controls.Add(child);
parent.Visible = true;
Response.Write(child.Visible + "<br />");
parent.Visible = false;
Response.Write(child.Visible + "<br />");
child.Visible = true;
Response.Write(child.Visible + "<br />");
parent.Visible = true;
Response.Write(child.Visible + "<br />");

What would you expect the output to be? Below is the output generated by the above code.

False
True
True
False
False

True

The marked values are not so obvious, but if we take into consideration, the fact that the Visible property is recursive, everything starts to make sense... or does it?

At first I thought that there should be more of those type of properties. It makes sense for a Visible property to be recursive since if we do not render a parent, we won't render a child. Why then, wouldn't the other, well known and widely used property: EnableViewState work in a similar way? If we repeat the same experiment we will get a different set of results:

Control parent = new Control();
Control child = new Control();
child.EnableViewState = false;
Response.Write(child.EnableViewState + "<br />");
child.EnableViewState = true;
Response.Write(child.EnableViewState + "<br />");
parent.Controls.Add(child);
parent.EnableViewState = true;
Response.Write(child.EnableViewState + "<br />");
parent.EnableViewState = false;
Response.Write(child.EnableViewState + "<br />");
child.EnableViewState = true;
Response.Write(child.EnableViewState + "<br />");
parent.EnableViewState = true;
Response.Write(child.EnableViewState + "<br />");

And results:

False
True
True
True
True

True

Notice, that this time we get what we set. Does it make sense? How is EnableViewState different from Visible? The functionality that depends on both of those properties only works if Parent works.

I'm not sure if there are more properties that work in a recursive way. I believe that it would be better if all properties worked that way which would make development more predictable. Unfortunately Visible is the only property that I know of that works in a recursive way, but there may be more. ASP.NET never stops to surprise me.

kick it on DotNetKicks.com

Tuesday, June 12, 2007 10:01:04 PM (Central European Standard Time, UTC+01:00)
Hi there

What you see in your example only happens because you can set the visible value but the getter does not only return the value that you set it, it is a calculated value implemented like so:

public virtual bool get_Visible()
{
if (this.flags[0x10])
{
return false;
}
if ((this._parent != null) && !this.DesignMode)
{
return this._parent.Visible;
}
return true;
}


The Enabled property also has a similar dependancy (this is a protected method), it traverses the parent hierarchy to determine if the control is enabled (Why didnt they implement this like get_visible? )

protected internal bool get_IsEnabled()
{
for (Control parent = this; parent != null; parent = parent.Parent)
{
if (parent.flags[0x80000])
{
return false;
}
}
return true;
}






However the getter for EnableViewState is simple

public virtual bool get_EnableViewState()
{
return !this.flags[4];
}






Wednesday, June 13, 2007 5:11:42 PM (Central European Standard Time, UTC+01:00)
I'd be surprised if ASP.NET stopped to surprise anyone, honestly... it seems like it's much too busy to be stopping all the time, surprising developers and such. :-D
kevboy
Wednesday, June 13, 2007 9:35:26 PM (Central European Standard Time, UTC+01:00)
To me this seems logical. It doesn't make sense to render a child if the parent is not visible. However it does make sense to set other properties of a child (like EnableViewState.

Greets
Rick
Rick
Wednesday, June 13, 2007 10:49:11 PM (Central European Standard Time, UTC+01:00)
It doesn't make sense to set EnableViewState property to True if parent has it set to False.
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview