服务器控件开发 —— Control 基类(1)
我们来看每个阶段Control控件里面都做了一些什么事情
1. Instantiate :
控件被页面或者另一控件调用, 实例化。
2. Initialize :
3. Begin Tracking View State :
4 Load View State :
在这一阶段控件通过 LoadViewStateRecursive 方法从ViewState 中还原状态。
5 Load Postback Data
对于需要加载回发数据的控件必须实现IPostBackDataHandler 接口
public interface IPostBackDataHandler
{
bool LoadPostData(string postDataKey, NameValueCollection postCollection);
void RaisePostDataChangedEvent();
}
在这一阶段 控件调用LoadPostData 接口方法来获取回发数据, 其中的postDataKey 表明回发数据的关键字 ,
NameValueCollection 是所有PostBack 的数据的集合。
返回值指示是否 激发 RaisePostDataChangedEvent 事件。
6 Load
这一阶段比较简单, 也是我们最常用的。
7 Raise Change Event
判断Load Postback Data 阶段的返回值, 如果返回True,就执行RaisePostDataChangedEvent()方法.
8 Raise PostBack Event
这一阶段只有单控件实现 IPostBackEventHandler 接口时执行。
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)。 该接口方法主要用来允许
开发者捕获PostBack 事件并执行自定义逻辑。 不好理解, 看看Button 控件的实现就明白了。
9 PreRender
看到这段代码之前也写过一些组合控件, 依样画葫芦 重写 ChildControlsCreated(), 一直以为
ChildControlsCreated()在控件生命周期的特定阶段被调用, 现在才知道以前的想法是错的。
基本上ChildControlsCreated() 是在第一次调用EnsureChildControls 的时候被创建,最晚是在Page Load
之后, PreRender 之前被调用, Control 类中另一个调用EnsureChildControls 的地方是在FindControl()
方法里面。 也就 是说一旦你调用了FindControl() 方法, 子控件就已经被自动创建。
10 SaveViewState
保存视图状态, 与Load ViewState 刚好相反。
11 Render
Render 阶段
看到这三个方法, 终于搞清楚了RenderControl, Render, RenderChildren 三个方法的区别。 这三个方法的设计 充分体现了通过组合, 而不是通过过程来实现的面向对象原则。
12 UnLoad
13 Dispose
这2 个阶段大同小异, 都是通过递归调用来卸载页面 释放资源。
我的下一篇文章将分析WebControl 是如何从Control 继承, 并实现自定义逻辑。