Web 服务器控件和 Html 服务器控件
一般地,在用 ASP.NET 开发 Web 应用程序时,时时刻刻都与控件打交道,可以说是无处不在,其实 Web 窗体页(.aspx 页)也是控件。
ASP.NET 控件分为 Web 服务器控件(简称 Web 控件)和 Html 服务器控件(简称 Html 控件),都是运行在服务器端。两者有什么区别呢?
我们平时用的 HTML 标记,如 <a>、<input> 等,是无法用程序来控制它们的,需用其它如 JavaScript 等程序语言才能得以控制。在 ASP.NET 程序里,我们可以在 HTML 标记加上 runat="server",就可以将相应的 HTML 标记变成 HTML 服务器控件,从而可以以编程的方式来控制这些 HTML 标记。引用(http://www.dvbbs.net/tech/net/2006051268338.asp ):
至于 Html 标注和 Html 控件之间的区别很明显,Html
控件是运行于服务器端,Html 标注是运行于客户端。具体来说:当 ASP.NET 网页执行时,会检查标注有无 runat
属性,如果标注没有设定,那么 Html 标注就会被视为字符串,并被送到字符串流等待送到客户端,客户端的浏览器会对其进行解释;如果 Html
标注有设定 runat="server" 属性,Page 对象会将该控件放入控制器,服务器端的代码就能对其进行控制,等到控制执行完毕后再将
Html 控件的执行结果转换成 Html 标注,然后当成字符串流发送到客户端进行解释。
对于 Web 服务器控件,是 Web 窗体页中用来定义 Web 应用程序用户界面的组件,是 Web Forms 编程模型的基本元素,尽管 Web 服务器控件呈现为 HTML,但它们的对象模型不一定反映 HTML 语法。
1、Asp.net 服务器控件提供更加统一的编程接口,如每个 Asp.net 服务器控件都有 Text 属性。
2、隐藏客户端的不同,这样程序员可以把更多的精力放在业务上,而不用去考虑客户端的浏览器是 ie 还是 firefox,或者是移动设备。
3、Asp.net 服务器控件可以保存状态到 ViewState 里,这样页面在从客户端回传到服务器端或者从服务器端下载到客户端的过程中都可以保存。
4、事件处理模型不同,Html 标注和 Html 控件的事件处理都是在客户端的页面上,而 Asp.net 服务器控件则是在服务器上。
创建自定义服务器控件
一、简述:
创建用户控件或服务器控件一般是继承于 System.Web.UI.Control 类或
System.Web.UI.WebControls.WebControl 类。如 Web 用户控件(.ascx 页)继承于
System.Web.UI.UserControl 类,后者继承于 System.Web.UI.TemplateContorl
类,后者又继承于 System.Web.UI.Control 类,而 Web 窗体页(.aspx 页)也继承于
System.Web.UI.TemplateContorl
类,为什么中间要多出这些类呢?这些中间类都主要是提供一些共享的属性、方法和事件,总不能把所有的功能都放在 Control
类吧。TemplateContorl 类为 Page 类和 UserControl 类提供一组基本功能。而 Control 类为所有
ASP.NET 服务器控件提供共享的属性、方法和事件,它作为开发自定义 ASP.NET
服务器控件时的派生源的主要类(为什么要说“的主要类”是因为开发这些控件时往往还要实现其它接口以完成更多功能)。咱们平时用得最多的
TextBox 控件则是继承于 System.Web.UI.WebControls.WebControl 类。后者同样也是继承于
System.Web.UI.Control 类。
Control 没有任何针对用户界面 (UI) 的功能。如果要创建没有 UI 的控件或者组合其他呈现它们自己的 UI 的控件,则从 Control 派生。如果要创建具有 UI 的控件,则从 WebControl 或 System.Web.UI.WebControls 命名空间中的任何控件派生,该命名空间为自定义控件提供适当的起点。
System.Web.UI.WebControls 命名空间包含一些呈现为 HTML 标记的类,如 TextBox 控件和 ListBox 控件。该命名空间还包含一些不在网页上呈现、但支持数据操作的类,如 SqlDataSource 类和 ObjectDataSource 类。其他一些控件(如 GridView 控件和 DetailsView 控件)支持数据显示和编辑。WebControl 类用作 System.Web.UI.WebControls 命名空间中许多类的基类。
二、例子:
1. 一个 MSDN 的例子,创建一个从 Control 类继承且无 UI 功能的控件:
// MyControl.cs
using System;
using System.Web.UI;
namespace DemoControl
{
public class MyControl : System.Web.UI.Control
{
protected override void Render(HtmlTextWriter writer)
{
if (HasControls() && (Controls[0] is LiteralControl))
{
writer.Write("<H2>Your Message : ");
Controls[0].RenderControl(writer);
writer.Write("</H2>");
}
}
}
}
然后在 aspx 页注册该控件并使用:
// Test.aspx
<%@ Page Language="C#" %>
<%@ Register TagPrefix="UC" Namespace="DemoControl" Assembly="Demo" %>
<UC:MyControl runat="server">
<asp:Literal runat="server" Text="http://pcvc.net" />
</UC:MyControl>
运行结果:
<H2>Your Message : </H2>
http://pcvc.net
2. 还是 MSDN 的例子:
namespace SpanControl
{
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
// Renders the following HTML:
// <span onclick="alert('Hello');" style="color:Red;">Custom Contents</span>
public class MyWebControl : WebControl
{
public MyWebControl() : base(HtmlTextWriterTag.Span)
{ }
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "alert('Hello');");
writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "Red");
writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "Pointer");
base.AddAttributesToRender(writer);
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("Custom Contents");
base.RenderContents(writer);
}
}
}
在 aspx 页注册该控件并使用:
// spancontrol.aspx
<%@ Page Language="C#" %>
<%@ Register TagPrefix="UC" Namespace="SpanControl" Assembly="Demo" %>
<UC:MyWebControl runat="server" />
运行结果:
<span onclick="alert('Hello');" style="color:Red;cursor:Pointer;">Custom Contents</span>