ASP.NET自定义控件开发点滴


1. 自定义控件从WebControl类而不是从Control类派生而来,那么就能够继承到许多附加的属性。
     比如高度,宽度,字体和其他样式相关的属性。这些属性可以允许页面开发者自定义控件的外观。当从WebControl类中派生时,应该遵循如下约定:
   ◎ 包含一个到System.Web.UI.WebControls命名空间的引用。
   ◎ 不要通过重载Render方法来直接向外输出流中写数据,这是因为WebControl的Render方法实现了一段代码,这段代码向外提供带有样式信息的标签。如果想在控件的标签内提供内容,那么可以用重载RenderContents方法来实现。

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

你可能感兴趣的:(html,object,C#,asp.net,button,events)