开发者

Nested Control Visibility Question

开发者 https://www.devze.com 2023-02-24 10:58 出处:网络
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\">

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消