TextBox控件中模板中,则只有在Page.PreRender时,我们才能得到控件实例,所以只在Page.PreInit中添加控件不行,我们还必须在PreRender时,看看这个TextBox有没有添加动态控件,如果添加了,再添加就要报错了,在Page.PreRender时添加控件,是我们的第二个难题 。
还好,这两个问题是一类问题,我们通过写一个HttpModuler,来帮助控件得到Page.PreInit和Page.PreRender事件,还要有一个HttpModuler和控件都能访问的地方:BaseTextBoxContext,来把所有的控件事件放在这里。代码如下:
BaseTextBoxContext
/// <summary> /// HttpModuler和控件的交互对象 /// </summary> public class BaseTextBoxContext { private static readonly string item_key = "::grain.basetextbox.context"; private static LocalDataStoreSlot GetSlot() { return Thread.GetNamedDataSlot(item_key); } /// <summary> /// 当前线程上下文的对象 /// </summary> public static BaseTextBoxContext Current { get { BaseTextBoxContext current = Thread.GetData(GetSlot()) as BaseTextBoxContext; if (current == null) { current = new BaseTextBoxContext(); Thread.SetData(GetSlot(), current); } return current; } } /// <summary> /// 移除线程上下文 /// </summary> public void RemoveContext() { Thread.FreeNamedDataSlot(item_key); } private List<EventHandler> preInitHandlers = new List<EventHandler>(); /// <summary> /// 控件的PreInit事件响应函数列表 /// </summary> public List<EventHandler> PreInitHandlers { get { return preInitHandlers; } } /// <summary> /// 添加一个PreInit时的响应函数 /// </summary> /// <param name="eventHandler"></param> public void AddPagePreInit(EventHandler eventHandler) { PreInitHandlers.Add(eventHandler); } private List<EventHandler> preRenderHandlers = new List<EventHandler>(); /// <summary> /// 控件的PreRender事件响应函数列表 /// </summary> public List<EventHandler> PreRenderHandlers { get { return preRenderHandlers; } } /// <summary> /// 添加一个PreRender时的响应函数 /// </summary> /// <param name="eventHandler"></param> public void AddPagePreRender(EventHandler eventHandler) { preRenderHandlers.Add(eventHandler); } }
BaseTextBoxModule
/// <summary> /// 帮助BaseTextBox响应Page.PreInit和Page.PreRender类 /// </summary> public class BaseTextBoxModule : IHttpModule { #region IHttpModule Members public void Dispose() { } public void Init(HttpApplication context) { |