2. 为控件选择基类
◎ 如果控件要生成非可视化的元素或者显示给非HTML客户端,那就因该从System.Web.UI.Control类派生。
标签<meta >和<xml>就是非可视化元素显示的例子。
◎ 如果想提供一些在客户端生成可视化界面的HTML,那么就应该从System.Web.UI.WebControls.WebControl派生。
◎ 当想扩展或者修改控件的功能时,应该从一个已经存在的控件派生,比如标签、按钮和文本框。可以任何一个System.Web.UI.WebControls命名空间中的控件或者自定义控件派生。但是不要从System.Web.UI.HtmlControls命名控件中的控件派生。
理解这部分,我们最好来看看WebContorl中Render方法的实现。
protected overide void Render(HtmlTextWriter writer){
RenderBeginTag(writer);
RenderContents(writer);
RenderEndTag(writer);
}
由此可见,WebControl中的Render已经被格式化了的。其中,RenderBeginTag表示标签的开始,如:writer.RenderBeginTag("<H2>") writer.RenderEndTag()即可表示包含在<H2></H2>
再来看看WebControl中的RenderContents实现代码:
protected virtual void RenderContents(HtmlTextWriter writer){
//可以看到RenderContents方法回调了基类的Render方法
base.Render(writer)
}
综上,当想要生成Web控件标签中的内容时,需要重载RenderContents方法。
======================================
今天先写到这里。
HtmlTextWriter
HtmlTextWriter的各种方法的参数取值为以下三种枚举类型:HtmlTextWriterTag,HtmlTextWriterAttribute和HtmlTextWriterStyle。这些枚举列举了HTML4.0的公共签名、attribute和CSS样式attribute。HtmlTextWriter中的很多方法都被重载,可以将字符串或者枚举值作为一个参数传送过去。
-----------------------------------------
委托和事件
我一直深受C#中委托和事件的影响,认为委托就是Delegate,事件是Event.哈哈,原来ASP.NET
中EventHandler就是所谓的委托。狂晕!
.NET Framework 中的事件模型基于具有事件委托,该委托将事件与事件处理程序连接。引发事件需要两个元素:
保存事件数据的类。该类必须从基类 EventArgs 派生。
指向方法的委托,该方法提供对事件的响应。
如果事件不生成数据,则使用事件数据对象的基类 EventArgs 和事件委托的预定义 EventHandler。
如: public delegate void EventHandler(Object sender, EventArgs e);
这是一个对不包含数据事件委托的声明,其中 EventHandler 是预定义的事件委托,sender 是引发事件的对象,而 e 是不包含数据的事件数据对象,EventArgs 是包含事件数据的类的基类。
----------------------------------------------
复合控件
EnsureChildControls() 方法是确认当前控件存在子控件。如果没有就新建一个。
复合控件可选择是否将子控件公开为属性,以及将子控件的哪些属性和事件公开为顶级属性和事件。
如下所示就是将button子控件的Text属性公开为ButtonText属性。
public string ButtonText {
get {
EnsureChildControls();
return _button.Text;
}
set {
EnsureChildControls();
_button.Text = value;
}
}
-----------------------------------------
关于事件优化
C#提供了“属性样式的事件声明”
基本格式为:
public event [委托类型] [事件名称]
{
add { .... }
remove { .... }
}
利用这个被称为“事件模型”的东西来建立事件委托。Control类为每个事件定义了一个键,用于EventHandler中存储和取回事件委托。
例如下面的代码显示了Logon事件的键。
private static readonly object EventLogon = new object();
键是静态的(在控件的所有实例间共享),因此仅为每个事件创建一次。下面的代码显示了C#事件的属性模型,这是一个Logon事件的声明。
public event EventHandler Logon {
add {
Events.AddHandler(EventLogon, value);
}
remove {
Events.RemoveHandler(EventLogon, value);
}
}
最后看看On<EventName>(处理事件)方法的实现。这种方法主要用来引发事件。当用事件的属性模型时,必须从EventHanderList中取回委托,然后在调用附加的处理程序前,将其转变成事件委托类型。
protected virtual void OnLogon(EventArgs e) {
EventHandler logonHandler = (EventHandler)Events[EventLogon];
if (logonHandler != null) {
logonHandler(this, e);
}
}
注:这里logonHandler已经是委托类型的实例,故而logon
注:System.ComponentModel.EventHandlerList 提供一个简单的委托列表。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=522409