2011-04-14 79 views
2

今天上午在处理错误时注意到了这一点。我有我的网页上是这样的:嵌套控制可见性问题

<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" 
      Style="font-weight: normal;"></asp:Label> 
    </div> 
</div> 

并在代码有这背后:

if(myCondition) 
    lblAttributeDropShipMsg.Visible = p.DropShipable; 
else 
    <snip> 

dvDropShipMsgWrap.Visible = p.DropShipable; 

跟踪代码,我发现lblAttributeDropShipMsg.Visible属性将永远是假的,即使设置为true也是如此。将其更改为:

dvDropShipMsgWrap.Visible = p.DropShipable; 
lblAttributeDropShipMsg.Visible = p.DropShipable; 

修复了这个问题。

看起来很奇怪,我无法在设置其父项之前设置嵌套控件的可见性。任何人都可以提供一些启发吗?

回答

7

我跑了一些测试,使用与您的示例中完全相同的声明标记。我的代码如下所示。右侧的注释显示了在执行每个注释左侧的代码之后,两个元素.Visible属性的值。我已经使用局部变量parentchild使事情变得更清晰。

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 

我认为第3行的结果可能是您观察到的行为。但是,这里的情况比起初看起来还要多。

如果您查看获取/设置控件的.Visible属性的CIL代码,您会发现设置控件的值实际上会影响内部位标志的值,而不管父级的可见性如何。但是,获取控件.Visible属性的值时,代码遍历从给定控件开始,直到其父项,然后到父项父项等的路径,直到控件层次结构的根。如果沿途任何控件的内部位标志指示“不可见”,则遍历停止,并返回值false。返回true的唯一方法是如果遍历使其成为根的所有路径,而没有找到任何不可见的控件。总而言之,设置一个控件的.Visible属性在内部被“记住”,但是如果其祖先的任何一个不可见,那么该属性的值将被返回为false。当控件的所有祖先都可见时,控件的.Visible属性的值将是上次设置时的“记忆”值。

+0

非常好的解释。谢谢。 – 2011-04-15 11:27:00