Noticed this while working through a bug this morning. I've got something like this on my page:
<div id="dvDropShipMsgWrap" runat="server" visible="false" class="systemMsgCon">
<div id="dvDropShipMsg" class="systemMsg plus">
<asp:Label ID="lblAttributeDropShipMsg" runat="server" ForeColor="#333333" Visible="false"
开发者_JAVA百科 Style="font-weight: normal;"></asp:Label>
</div>
</div>
And had this in the code behind:
if(myCondition)
lblAttributeDropShipMsg.Visible = p.DropShipable;
else
<snip>
dvDropShipMsgWrap.Visible = p.DropShipable;
Tracing the code, I found that the lblAttributeDropShipMsg.Visible property would always be false, even when setting it to true. Changing it to this:
dvDropShipMsgWrap.Visible = p.DropShipable;
lblAttributeDropShipMsg.Visible = p.DropShipable;
fixed the problem.
It seems weird that I can't set the nested control's visibility before setting its parent. Can anybody provide some enlightenment?
I ran some tests, using exactly the same declarative markup as in your example. My code behind is shown below. Comments on the right show the values of the two elements' .Visible
properties, after the code to the left of each comment executes. I've used local varialbes parent
and child
to make things a bit clearer.
1 var parent = dvDropShipMsgWrap; // parent child
2 var child = lblAttributeDropShipMsg; // false false (initial values)
3 child.Visible = true; // false false
4 parent.Visible = true; // true true
5 parent.Visible = false; // false false
6 child.Visible = false; // false false
7 parent.Visible = true; // true false
I think the result on line 3 is probably the behavior that you observed. But there's more going on here than it may seem at first.
If you look at the CIL code that gets/sets a control's .Visible
property, you will find that setting a control's value actually does affect the value of an internal bit flag, regardless of the visibility of the parent. However, when getting the value of a control's .Visible
property, the code traverses a path starting at the given control, up to its parent, then to the parent's parent, and so on, up toward the root of the control hierarchy. If the internal bit flag of any control along the way indicates "not visible", the traversal stops, and the value false
is returned. The only way to return true
is if the traversal makes it all the way to the root, without finding any control that is not visible.
So, to sum up, setting a control's .Visible
property is "remembered" internally, but the value of the property will be returned as false
if any of its ancestors is not visible. When the all the ancestors of the control are made visible, the value of the control's .Visible
property will be the "remembered" value from when it was last set.
精彩评论