ASP.NET中的Web控件介绍
一、HTML控件
就是我们通常的说的html语言标记,这些语言标记在已往的静态页面和其他网页里存在,不能在服务器端控制的,只能在客户端通过javascript等程序语言来控制。
<input type="button" id="btn" value="button"/>
二、HTML服务器控件
其实就是html控件的基础上加上runat="server"所构成的控件。它们的主要区别是运行方式不同,html控件运行在客户端,而html服务器控件是运行在服务器端的。
当ASP.NET网页执行时,会检查标签有无runat属性,如果标签没有设定,那么Html标签就会被视为字符串,并被送到字符串流等待送到客户端,客户端的浏览器会对其进行解释;如果Html标签有设定runat="server" 属性,Page对象会将该控件放入控制器,服务器端的代码就能对其进行控制,等到控制执行完毕后再将Html服务器控件的执行结果转换成Html标签,然后当成字符串流发送到客户端进行解释,不能通过js来控制它。因为当控件属性中有runat="server"时,生成的html控件时name和id发生的变化。
HTML 服务器控件 (HTML server control)属于 System.Web.UI.HtmlControls 命名空间的 ASP.NET 服务器控件。
<form runat="server"> <input runat="server" type="button" id="delete" value="Server button" onserverclick="delete_ServerClick" /> <input type="button" onclick="return DeleteCheck(this)" id="Button1" value="Client button" /> <input runat="server" type="submit" onclick="return DeleteCheck(this)" id="Button2" value="Server submit" /> <input type="submit" onclick="return DeleteCheck(this)" id="Button3" value="Client submit" /> <button runat="server" id="button4" onclick="return DeleteCheck(this)" value="Button-Button">Button-Button</button> </form>
生成的html代码:
当html服务器控件在服务器端添加了服务器事件(onserverclick)后客户端生成的代码变为:onclick="_doPostBack()",实际上是调用脚本把整个窗体提交到服务器(如果没有添件服务器事件而只是添加了runat="server"是不会发送到服务器端的)
<form> <input language="javascript" onclick="__doPostBack('delete','')" name="delete" type="button" id="delete" value="Server button" /> <input type="button" onclick="return DeleteCheck(this)" id="Button1" value="Client button" /> <input name="Button2" type="submit" id="Button2" onclick="return DeleteCheck(this)" value="Server submit" /> <input type="submit" onclick="return DeleteCheck(this)" id="Button3" value="Client submit" /> <button id="button4" onclick="return DeleteCheck(this)" value="Button-Button">Button-Button</button> </form>
JS脚本:
<script type="text/javascript"> <!-- var theForm = document.forms['form1']; if (!theForm) { theForm = document.form1; } function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); } } // --> </script>
HTML控件,如IMG的输入按钮等 的 onclick ( 客户端 )和 onserverclick( 服务端 )事件,注意 runat="server"。此处的onclick先于onserverclick执行。
三、Web服务器控件
也称asp.net服务器控件,是Web Form编程的基本元素,也是asp.net所特有的。它会按照client的情况产生一个或者多个html控件,而不是直接描述html元素。
Web 服务器控件比 HTML 服务器控件更丰富、更抽象。Web 服务器控件在 asp.net 页上有 asp 标记前缀,例如 <asp:Button runat=“server” />。属于 System.Web.UI.WebControls 命名空间的ASP.NET服务器控件。
<asp:Button ID="Button2" runat="server" Text="Button"/>
当asp:button服务器按钮通过生成的页面后转化成类型为submit类型的Client控件。
<input type="submit" name="Data$ctl03$button2" value="Button" onclick="return DeleteCheck(this);" id="Data_ctl03_button5" />
Web服务器控件和html服务器控件的区别
1)、Asp.net服务器控件提供更加统一的编程接口,如每个Asp.net服务器控件都有Text属性。
2)、隐藏客户端的不同,这样程序员可以把更多的精力放在业务上,而不用去考虑客户端的浏览器是ie还是firefox,或者是移动设备。
3)、Asp.net服务器控件可以保存状态到ViewState里,这样页面在从客户端回传到服务器端或者从服务器端下载到客户端的过程中都可以保存。
4)、事件处理模型不同,Html标签和Html服务器控件的事件处理都是在客户端的页面上,而Asp.net服务器控件的事件处理则是在服务器上。
WEB控件,如<asp:button> 按钮等 的 onclientclick( 客户端 ) 先于 onclick ( 服务端 )事件执行。
总之:客户端点击事件先于服务器端点击事件执行。也就是说,先执行客户端的Javascript,然后到服务器端执行服务器的相关代码。
四、Web用户控件
https://www.jb51.net/article/247144.htm
五、Web自定义控件
自定义控件需要定义一个直接或间接从Control类派生的类,并重写Render方法。在.NET框架中,System.Web.UI.Control与System.Web.UI.WebControls.WebControl两个类是服务器控件的基类,并且定义了所有服务器控件共有的属性、方法和事件,其中最为重要的就是包括了控制控件执行生命周期的方法和事件,以及ID等共有属性。
1、用户控件和自定义控件的异同
- 使用率
在选择使用用户控件和自定义控件时,可以首先考虑使用率。如果开发的应用程序只是需要小范围的使用,则可以考虑用户控件,而如果开发的自定义控件能够在大部分的应用程序中被应用,则可以考虑自定义控件。 - 创建技术
用户控件和自定义控件的创建技术是不相同的,并且用户控件和自定义控件创建的难度也不相同,用户控件是以.ascx形式声明并创建的,开发过程也比较简单,并且有设计器提供设计支持,而自定义控件是从System.Web.UI.Control派生而来的,开发过程稍微复杂,也没有设计器提供设计支持。 - 生成方式
用户控件和自定义控件生成的方式不同,用户控件是以.ascx的形式呈现,而自定义控件是以DLL的形式呈现,通过添加引用,自定义控件能够在【工具箱】中显式,能够像服务器控件一样拖动到页面,并且能够通过编程开发增加自定义属性。而用户控件无法在工具箱显示,也不能够像自定义控件那样增加自定义属性。 - 性能
虽然用户控件和自定义控件编写的过程不同,也遵循不同的创建模型,但是用户控件和自定义控件都是从System.Web.UI.Control直接或间接的派生的,在性能上没有很大的差别,主要是因为当用户控件在页面中第一次使用时,将作为普通的服务器控件被解析并编译进配件,第二次使用时,就和其他编译型控件一样。
实现自定义控件,必须创建一个自定义控件,自定义控件将会编译成DLL文件。
2、实现自定义控件
自定义控件创建完成后,会自动生成一个类,并在类中生成相应的方法,示例代码如下所示。
开发人员可以在源代码中编写和添加属性。当需要呈现给HTML页面输出时,只需要重写RenderContents方法即可.
为了实现服务器控件的智能属性配置,开发人员能够在源代码中编写属性。
[DefaultProperty("Text")] //声明属性 [ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")] //设置控件格式 public class ServerControl1 : WebControl { [Bindable(true)] //设置是否支持绑定 [Category("Appearance")] //设置类别 [DefaultValue("")] //设置默认值 [Localizable(true)] //设置是否支持本地化操作 public string Text //定义Text属性 { get { String s = (String)ViewState["Text"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Text"] = value; } } //为了实现服务器控件的智能属性配置,开发人员能够在源代码中编写属性 public string GuoJingString //编写属性 { get { return (String)ViewState["GuoJingString"]; } set { ViewState["GuoJingString"] = value; } } protected override void RenderContents(HtmlTextWriter output) //页面呈现 { output.Write("定义的Text属性的值为:" + Text); //输出为页面呈现 } }
当自定义控件编写完毕后,需要在需要使用该控件的项目中添加引用。在工具栏中会呈现自定义控件,自定义控件呈现在工具箱之后,就可以直接拖动自定义控件到页面,并且配置相应的属性。
用户拖动自定义页面到控件后,页面会在头部声明自定义控件,生成相应的自定义控件的HTML代码。
向页面注册了自定义控件,自定义注册完毕后,就能够在页面中使用该控件。
<%@ Register TagPrefix="MyControl" Namespace="ServerControl1" Assembly="ServerControl1" %> <form id="form1" runat="server"> <div> <MyControl:ServerControl1 ID="ServerControl11" runat="server" /> </div> </form>
3、复合自定义控件
复合自定义控件就是功能复杂的控件。编写复合自定义控件有以下几种方式:
- 创建用户控件,并使用用户控件封装的用户界面实现复合控件。
- 开发一个编译控件,封装一个按钮控件和文本框控件,通过重写Render方法呈现。
- 从现有的控件中派生出新控件。
- 从基本控件类之一派生来创建自定义控件。
通过编写复合控件,能够让控件开发更加灵活,控件的使用人员也能够更加方便的配置控件,
例如,重写登录控件,前台页面制作人员使用该控件时,可以为控件配置验证等功能,方便前台人员配置和使用。
1、ASP.NET登录控件的开发
public class ServerControl1 : WebControl { //创建服务器控件 public TextBox NameTextBox = new TextBox(); //创建TextBox控件 public TextBox PasswordTextBox = new TextBox(); //创建密码控件 public Button LoginButton = new Button(); //创建Button控件 [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string LoignBackGroundColor //设置背景属性 { get { return (String)ViewState["LoignBackGroundColor"]; } set { ViewState["LoignBackGroundColor"] = value; } } protected override void RenderContents(HtmlTextWriter output) //编写页面输出 { output.RenderBeginTag(HtmlTextWriterTag.Div); //创建Div标签 output.RenderBeginTag(HtmlTextWriterTag.Tr); //创建Tr标签 NameTextBox.RenderControl(output); //添加控件 output.RenderBeginTag(HtmlTextWriterTag.Td); //创建Td标签 output.RenderBeginTag(HtmlTextWriterTag.Br); //创建Br标签 output.RenderBeginTag(HtmlTextWriterTag.Tr); //创建Tr标签 PasswordTextBox.RenderControl(output); //添加控件 output.RenderBeginTag(HtmlTextWriterTag.Td); //输出Td标签 } public event EventHandler LoginClick; //声明事件 public void Submit_Click(object sender, EventArgs e) { EventArgs arg = new EventArgs(); //编写按钮事件方法 if (LoginClick != null) //判断事件冒泡是否为空 { LoginClick(LoginButton, arg); //触发事件 } } }
2、ASP.NET登录控件的使用
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="_11_4._Default" %> <%@ Register TagPrefix="Sample" TagName="Login" Src="~/LoginForm.ascx" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <Sample:Login runat="server" id="Login1"></Sample:Login> </div> </form> </body> </html>
4、自定义分页控件
[DefaultProperty("Text")] //默认属性 [ToolboxData("<{0}:MyPager runat=server></{0}:MyPager>")] //控件呈现代码 public class MyPager : WebControl { [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text //Text文本属性 { get { String s = (String)ViewState["Text"]; return ((s == null) ? "[" + this.ID + "]" : s); } set { ViewState["Text"] = value; } } [Bindable(true)] [Category("Data")] [DefaultValue(10)] [Localizable(true)] public int PageSize //分页数属性 { get { try { Int32 s = (Int32)ViewState["PageSize"]; return ((s.ToString() == null) ? 10 : s); } catch { return 10; } } set { ViewState["PageSize"] = value; } } [Bindable(true)] [Category("Data")] [DefaultValue("")] [Localizable(true)] public string IndexPage //索引页面 { get { String s = (String)ViewState["IndexPage"]; return ((s == null) ? ("none") : s); } set { ViewState["IndexPage"] = value; } } [Bindable(true)] [Category("Data")] [DefaultValue("")] [Localizable(true)] public int Rows //总行数 { get { int s = (int)ViewState["Rows"]; return ((s.ToString() == null) ? 0 : s); } set { ViewState["Rows"] = value; } } protected override void RenderContents(HtmlTextWriter output) { string html = ""; int pageCount = 0; //分页数 if (Rows % PageSize > 0) //开始分页 { pageCount = (Rows / PageSize) + 1; //分页计算 } else { pageCount = Rows / PageSize; } html += "<table><tr>"; for (int i = 0; i < pageCount; i++) { if (IndexPage != i.ToString()) //如果查看的是当前页面,则高亮显示 { html += "<td style=\"padding:5px 5px 5px 5px;background:#f0f0f0;border:1px dashed #ccc;\">"; //呈现相应的HTML } else { html += "<td style=\"padding:5px 5px 5px 5px;background:Gray;border:1px dashed #ccc;\">"; //呈现相应的HTML } html += "<a href=\"pages.aspx?page=" + i + "\">" + i + "</a>"; html += "</td>"; //完成HTML } html += "</tr></table>"; output.Write(html); //页面呈现 } }
何其他的应用程序如果需要使用分页控件,则需要首先添加引用。
使用自定义控件并配置相应的属性:
<%@ Register TagPrefix="MyControl" Namespace="MyPager" Assembly="MyPager" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <MyControl:MyPager ID="MyPager1" runat="server" DataBase="mytable" IndexPage="1" PageName="default.aspx" PageSize="1" Pwd="Bbg0123456#" Table="mynews" Uid="sa" /> </div> </form> </body> </html>