开发ASP.NET定制控件

定制控件的价值:1.代码重用   2.快速页面开发   3.通过控件,使修改页面更加容易

什么是ASP.NET控件?
服务器端Web UI组件:它有属性、方法和事件;呈现成标注(HTML,XML,script,etc);处理posted数据和用户行为;封装逻辑;多种呈现选项。一个控件是一个.NET类型,基类是System.Web.UI.Control,System.Web.UI.WebControls.WebControl

页面/控件处理
第一次载入:Init(实例化每个控件,设置为初始状态,加入控件树)--》Load(运行用户代码,测试IsPostBack条件来数据绑定到第一批值)--》PreRender(CreateChildControls()确保控件准备好被呈现)--》控件存储状态值(如果与初始值不同)--》Render(每个控件将自身呈现到响应中)--》Dispose(释放页面和所有控件)

Postback:比上述多了三个步骤,在Init和Load中加了个LoadViewState(从ViewState载入控件的上一次状态);在Load和PreRender之间加入了Postback data(posted数据(HTTP表单中)传递到响应控件)和postback(按照在树中的次序触发控件事件,除了导致Post的控件,它最后触发)

两种创建控件的方法:
用户控件(页面作为控件):容易创建,存作为(.ascx) 的页面,支持部分页面缓存,用于单个应用,缺少设计时支持。运行时动态编译,无法添加到工具箱,共享它的唯一方法是将之复制到另一个应用程序中。
定制控件:技术要求高一些,支持多个应用(GAC),设计时支持非常强大。它是所有开发人员都可以使用的可视化设计工具。

为设计时呈现(Render)实施一个控件设计器:
System.Design.dll提供了设计时呈现的基类。
Override GetDesignTimeHtml()默认的设计时输出内容
设计时和运行时的HTML输出是不同的处理方式
Designer类在控件的属性列表中被指定

使用呈现(Render)方法:
从Control类继承时,使用Render()方法;
从WebControl类继承时,覆盖RenderContents方法;
控件的默认基本标签是<span>标签;
当创建一个继承类的实例时,需要指定哪个基类的构造函数需要被调用,例如base(HtmlTextWriterTag.A)就是创建<a>标记
使用AddAtributesToRender()方法为控件添加HTML属性和风格。

触发服务器端事件
将服务器端客户事件映射到服务器事件
客户端的事件通过HTTP表单发一个POST至服务器端,服务器端的注册控件以接收postback事件通知。控件注册是通过委派delegate的数据类型事件会触发相应的方法去注册。如果希望自己开发的控件能够触发相应的事件,定义的类必须从IPostBackEventHandler继承过来,它是一个接口继承,它会触发一个postback事件,这个事件调用了事件处理函数,比如:Button1_Click()
用到的接口为IPostBackEventHandler(定义了ASP.NET服务器控件必须实现的方法来处理),相应的函数是RaisePostBackEvent(),触发OnClick(),调用事件处理函数Button1_Click()

使用HtmlTextWriter方法
HtmlTextWriter具备在不同的HTML版本之间,自动转换的功能,可以适应不同的浏览器。
多次调用HtmlTextWriter.Write,比构造一个复杂的字符串,然后作为参数调用一次,效率要更高。
HtmlTextWriter方法使得代码可读性和可用性更高

开发组合控件
INamingContainer接口确定容器控件在页面的对象结构下,创建一个新的名称控件ID,也就是它为某个.ASPX文件中的所有控件提供一个唯一的名称控件。
EnsureChildControls()确定服务器控件是否包含子控件,如果不包含,它将创建子控件。
CreateChildControls()通知服务器控件创建它所包含的所有子控件。

定制控件的使用范例
通过一些预定义的类,定制控件可以被快速开发出来,例如Table,HyperLink以及Label
可以用Postback事件处理来传递客户端可视化数据到后端数据库
创建配置文件(例如topLinks.xml)为web应用程序提供了一种快速并且高效的解决方案

总结:
WebControl类从Control类继承过来,增加了一些web用户控件的通用属性
把控件项目和web应用程序项目添加到同一个解决方案中,可以更加容易调试,构建,以及测试和开发。
控件可以添加到工具箱,或者全局程序集缓冲区(GAC),以便更多的开发人员都可以使用。
组合控件被编译为一个固定的程序集(.dll)
HtmlTextWriter提供了很多实用的方法来简化HTML标记的构造。
在客户端Post到服务器时,RaisePostBackEvent被触发,从而服务器控件可以进行相应的处理。

实例1:创建一个简单的定制控件
1.新建“web控件库项目”,可以看到控件继承自WebControl,
2.编译此项目,可在bin目录中看到已生成的.dll组件
3.在同一个解决方案中加入一个asp.net web应用程序
4.在工具箱的常规选项中右击选择“添加/移除项”,将刚才生成的组件选入
5.在WebForm1.aspx的设计界面中将刚在工具箱上生成的组件拖放至界面中。
6.在控件的文本属性中输入“Hello,Control!"
7.在自定义控件中添加一个Speed属性,用于控制滚动速度
8.在Render事件中增加 output.Write("<marquee scrollDelay=/""+Speed.ToString()+"/">"+Text+"</marquee>");
9.在控件属性栏中可见Speed属性,设值为1000,可见滚动速度变慢

实例2:修改工具箱中组件的图标
1.在组件项目中添加一个位图文件,名称与控件名称相同
2.设计位图文件
3.在位图的属性中有一个“生成操作”属性,修改其值为“嵌入的资源”
4.编译,将web应用程序项目工具箱中的组件移除,重新添加,可看到更改的图标

实例3:为设计时呈现(Render)实施一个控件设计器,添加一个设计类
1.在控件项目中添加一个Designer.cs的类文件,添加System.IO; System.Web.UI;System.Web.UI.WebControls的引用
2.在组件项目中添加引用System.Desinger.dll
3.为Designer类添加基类public class Designer:System.Web.UI.Design.ControlDesigner
4.重新Designer基类的方法public override string GetDesignTimeHtml(),小技巧:在输入public override后直接输入Get……会自动出现下拉列表,直接选择GetDesignTimeHtml会自动添加整个函数
5.修改GetDesignTimeHtml方法,添加字符串StringWriter sw=new StringWriter();添加HtmlTextWriter tw=new HtmlTextWriter();返回字符串return sw.ToString();
6.重新编译代码生成组件
7.修改自定义控件属性,Designer("WebControlLibrary1.Designer,WebControlLibrary1"),DefaultProperty("Text")
8.重新编译,可以看到web应用程序中设计的呈现已经被修改,但执行的结果不变
9.继续在GetDegnTimeHtml方法中添加方法

   HyperLink hl=new HyperLink();
   hl.Text="Hello,Control";
   hl.NavigateUrl="http://www.microsoft.com";
   hl.RenderControl(tw);
  
   tw.Write(HtmlTextWriter.SpaceChar);
   Label lbl=new Label();
   lbl.Text=hl.NavigateUrl;
   lbl.BackColor=System.Drawing.Color.AliceBlue;

完成后可在设计界面中看到上述的改动

实例4:继承自Control和WebControl类的区别,Control类定义了最基本的属性,WebControl继承自Control,额外定义了许多属性,可以在自定义类修改继承的类后在web应用程序中调用的该控件属性栏中看到区别。

实例5:如何使用Render方法
1)    Render方法在控件类中,它不显示属性,如
"Hello,Control"<marquee scrollDelay="10">"Hello,Control"</marquee>
为了增加属性,将Render改为RenderContents,它会将可视化的属性都添加进来,放在<span>标记中
如:<span id="WebCustomControl11" style="height:8px;width:32px;Z-INDEX: 101; LEFT: 136px; POSITION: absolute; TOP: 136px">"Hello,Control"<marquee scrollDelay="100">"Hello,Control"</marquee></span>

2)   将RenderContents的语句改为
 HyperLink hl=new HyperLink();
   hl.NavigateUrl="http://www.microsoft.com";
   hl.RenderControl(output);
编译控件执行web应用程序生成的代码为:
<span id="WebCustomControl11" style="height:8px;width:32px;Z-INDEX: 101; LEFT: 136px; POSITION: absolute; TOP: 136px"><a href="http://www.microsoft.com">hello,control!</a></span>

3) span标记可以修改,只需要定义类的构造函数
举例:创建类的构造函数,并让它继承基类public WebCustomControl1():base(HtmlTextWriterTag.A);添加AddAttributesToRender函数:
writer.AddAttribute(HtmlTextWriterAttribute.Onclick,"alert('You choose a page out of this site');");
   writer.AddAttribute(HtmlTextWriterAttribute.Href,"http://www.tom.com");
   base.AddAttributesToRender (writer);
为基类标记添加属性并显示
修改RenderContents函数,只需显示文本:output.Write(Text)(注意:文本的其他属性已经被构造函数所添加)
编译控件执行web应用程序生成的代码为:
<a οnclick="alert('You choose a page out of this site');" href="http://www.tom.com" id="WebCustomControl11" style="height:8px;width:32px;Z-INDEX: 101; LEFT: 136px; POSITION: absolute; TOP: 136px">"Hello,Control"</a>

实例6:处理postback事件
为已生成的控件类添加继承IPostBackEventHandler,再按Tab键会自动生成RaisePostBackEvent的方法,这个方法是这个被继承接口必须实现的方法,也就是必须触发一个事件
在定义这个方法之前,先定义一个事件,它相当于一个委托的数据类型。public event EventHandler Click;
再定义一个触发的事件方法
protected virtual void OnClick(EventArgs e)
  {
   if (Click!=null)
   {
    Click(this,e);
   }
   Page.Response.Redirect("http://www.microsoft.com");
  }
接着实现RaisePostBackEvent方法,调用OnClick(EventArgs.Empty);
还需要修改AddAttributesToRender函数,将writer.AddAttribute(HtmlTextWriterAttribute.Href,"http://www.tom.com");语句改为writer.AddAttribute(HtmlTextWriterAttribute.Href,"javascript:"+Page.GetPostBackEventReference(this));说明:Page.GetPostBackEventReference是客户端脚本的引用,它会执行客户端脚本,触发相应的事件执行。
编译执行web应用程序生成的代码为
<a οnclick="alert('You choose a page out of this site');" href="javascript:__doPostBack('WebCustomControl11','')" id="WebCustomControl11" style="height:8px;width:32px;Z-INDEX: 101; LEFT: 136px; POSITION: absolute; TOP: 136px">"Hello,Control"</a>

以上都是在控件中实现的功能,如果使使用控件的开发者也能捕捉控件事件
在使用控件的web页面中添加方法
  private void WebCustomControl1_Click(object sender,System.EventArgs e)
  {
   TextBox1.Text="Clicked!";  说明:TextBox1为文本输入框ID

理WebCustomControl11.Click+=new EventHandler(this.WebCustomControl1_Click);

实例7:使用HtmlTextWriter方法
在RenderContents中添加语句:
output.AddAttribute(HtmlTextWriterAttribute.Size,"18"); 
   output.RenderBeginTag(HtmlTextWriterTag.Font);
   output.Write(Text);
   output.RenderEndTag();
修改AddAttributesToRender函数,将writer.AddAttribute(HtmlTextWriterAttribute.Href,"javascript:"+Page.GetPostBackEventReference(this));语句改为writer.AddAttribute(HtmlTextWriterAttribute.Onclick,"javascript:"+Page.GetPostBackEventReference(this));
编译执行查看文本显示
也可以在属性中添加风格,如在AddAttributersToRender方法中添加如下代码

  protected override void AddAttributesToRender(HtmlTextWriter writer)
  {
   //writer.AddAttribute(HtmlTextWriterAttribute.Onclick,"alert('You choose a page out of this site');");
   //writer.AddAttribute(HtmlTextWriterAttribute.Href,"http://www.tom.com");
   writer.AddAttribute(HtmlTextWriterAttribute.Onclick,"javascript:"+Page.GetPostBackEventReference(this));
   writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor,"darkgreen"); //设置属性背景色为暗绿
   writer.AddStyleAttribute(HtmlTextWriterStyle.TextDecoration,"underline"); //设置下划线
   writer.AddAttribute("onmouseover","this.style.cursor='hand'"); //设置鼠标滑过时为手形
   base.AddAttributesToRender (writer);
  }

实例8:开发组合控件
1.首先创建一个asp.net应用程序,并在解决方案中添加控件库项目
2.编写控件代码
public class ctrl:Control,INamingContainer
 {
  public int Value
  {
   get
   {
    this.EnsureChildControls();//确保所有子控件已创建,如果没有创建,调用CreateChildControls( )方法
    return Int32.Parse(((TextBox)Controls[1]).Text);
   }
   set
   {
    this.EnsureChildControls();
    ((TextBox)Controls[1]).Text=value.ToString();
   }
  }

  protected override void CreateChildControls()  //重写CreateChildControls方法创建子控件
  {
   this.Controls.Add(new LiteralControl("<label>Sum</label>"));
   TextBox tb=new TextBox();
   tb.Text="";
   this.Controls.Add(tb);
   this.Controls.Add(new LiteralControl("<br>"));
  }

 }
编译该组件,并在工具箱中添加它
在asp.net web应用程序中添加两个文本框,一个标签和一个按钮,并拖放生成的控件,组成一个加法界面,在按钮点击事件中添加加法逻辑
执行程序测试可以看到控件生成的一个标签和一个文本框

自定义控件的使用范例
演示如何使用控件创建应用,使应用更利于维护

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值