ASP.NET 控件 - 控件之间的关系






3.78/5 (16投票s)
这是我关于 ASP.NET 控件系列的又一篇小型文章,其主要重点在于揭示控件之间的关系,涉及哪些实体,以及它们在此任务中的主要作用。
引言
这是我关于 ASP.NET 控件系列的又一篇小型文章,其主要重点在于揭示控件之间的关系,涉及哪些实体,以及它们在此任务中的主要作用。
动机
理解我们每次处理页面请求并在浏览器中显示 Web 窗体时发生在幕后的那些神奇的小细节,将有助于您避免许多问题,更快地进行调试,并构建更出色的应用程序。
如果您是经验丰富的程序员,这些知识还将帮助您协调复杂的变通方法,并可能深入了解 ASP.NET 的一些限制。
控件之间是如何相互关联的?
为了公开一个 ASP.NET 窗体,您需要将其放置在一个 Page
中,实际上,放置在任何 ASP.NET 控件中。为了参与 页面生命周期,您需要以某种方式与 Page 相关联。这种关系是通过父/子层级结构实现的。
Page
控件是这种层级关系中的根控件,它负责处理应该触发哪个管道(初始请求、回发请求或回调请求)。
如果需要,一个控件可以包含其他控件,所有这些子控件都保存在一个 ControlCollection
实例中,该实例通过 Controls
属性公开。每个控件都知道它的 Parent
控件。
一个可以包含其他控件的控件也可以被标记为自动为其后代生成名称的过程的参与者。这个角色是通过实现 INamingContainer
接口来实现的,当这种情况发生时,该控件被称为 NamingContainer
。每个子控件都知道它的 NamingContainer
。
ControlCollection
提供了通常的集合管理方法集。
Add
- 将指定的Control
对象添加到集合中。Remove
- 从父服务器控件的ControlCollection
对象中移除指定的服务器控件。Clear
- 从当前服务器控件的ControlCollection
对象中移除所有控件。
控件只能通过 ControlCollection.Add
方法附加到另一个控件并成为其子控件。每次将控件添加或从集合中移除时,其父控件和 NamingContainer
都会收到通知并做出响应。
当一个控件被添加到另一个控件的子集合时,新的父控件的 Control.AddedControl
方法会被调用,并执行以下步骤:
- 检查新添加的子控件是否具有所有者,因此其使用是否仅限于该所有者控件。如果为真,则该子控件不是有效控件,并会抛出异常。
- 检查新添加的子控件是否属于另一个控件的子集合,在这种情况下,该控件将从其先前的父控件的子集合中移除。这是为了确保有效的层级关系:一个控件只能属于一个
ControlCollection
。 - 更新新添加的子控件的 Page 引用,使其指向新的父 Page。
- 更新新添加的子控件的父引用,使其指向自己。如果新的父控件是一个
NamingContainer
,那么我们将更新新添加的子控件的NamingContainer
引用,使其指向自己。 - 如果新子控件的 ID 未指定,则会自动为新子控件的
NamedControls
集合生成一个新的 ID,并且NamingContainer
会被标记为脏,以确保创建一个新的、干净的集合并填充它。 - 如果可能,会为新添加的子控件重新创建控件生命周期。
当一个控件从其父 ControlCollection
中移除时,父控件的 Control.RemovedControl
方法会被调用,并执行以下步骤:
- 检查新添加的子控件是否具有所有者,因此其使用是否仅限于该所有者控件。如果为真,则该子控件不是有效控件,并会抛出异常。
- 子控件
NamingContainer
的NamedControls
集合会被标记为脏,以确保创建一个新的、干净的集合并填充它(不包含已移除的控件)。 - 子控件执行
UnloadRecursive
,但不进行处置。 - 在
AddedControl
中设置的所有引用都会被移除,并且该控件将从任何层级中释放。