http://www.cnblogs.com/Clingingboy/archive/2006/09/17/506741.html
这个地方写的自定义控件教程不错!!
Control类
这是在开发自定义 ASP.NET 服务器控件时作为派生源的主要类。Control 没有任何针对用户界面 (UI) 的功能。如果创作没有 UI 的控件或者组合其他呈现它们自己的 UI 的控件,则从 Control 派生。如果创作具有 UI 的控件,则从 WebControl 或 System.Web.UI.WebControls 命名空间中的任何控件派生,该命名空间为自定义控件提供适当的起点。
Control 类是包括自定义控件、用户控件和页在内的所有 ASP.NET 服务器控件的基类。ASP.NET 页是 Page 类(该类从 Control 类继承)的实例,并且处理对扩展名为 .aspx 的文件的请求。
HtmlTextWriter 类用于向桌面浏览器呈现 HTML 4.0。HtmlTextWriter 也是 System.Web.UI 命名空间中所有标记编写器的基类,这些编写器包括 ChtmlTextWriter、Html32TextWriter 和 XhtmlTextWriter 类。这些类用于针对不同的标记类型编写元素、属性、样式和布局信息。此外,与每种标记语言相关联的页和控件适配器类也使用这些类。
大多数情况下,ASP.NET 会自动为请求设备使用合适的编写器。但是,如果创建自定义文本编写器或者要为某个设备指定特定的编写器来呈现某页,则必须在应用程序的 .browser 文件的 controlAdapters 节中将相应的编写器映射到该页。
System.ComponentModel 命名空间提供用于实现组件和控件运行时和设计时行为的类。此命名空间包括用于实现属性和类型转换器、绑定到数据源以及授权组件的基类和接口。
该命名空间中的类分为以下类别:
核心组件类。请参见 Component、IComponent、Container 和 IContainer 类。
组件授权。请参见 License、LicenseManager、LicenseProvider 和 LicenseProviderAttribute 类。
属性。请参见 Attribute 类。
说明符和持久性。请参见 TypeDescriptor、EventDescriptor 和 PropertyDescriptor 类。
类型转换器。请参见 TypeConverter 类。
会发现工具箱已经自动帮你加上了这几个控件???????????????
生成网站后工具箱没有哪个控件 只有个名字
要注意一点 ToolboxData(@"<{0}:CreditCardForm2 项目名称要注意一致
HtmlTextWriter类提供几个有用的方法用来代替.
(1)AddStyleAttribute方法 为标签添加样式属性
(2)AddAttribute方法 为标签添加属性
(3)RenderBeginTag 开始写入标签头 如<table....>
(4)RenderEndTag 写入标签尾部,如</table>
这里有几点需要特别注意.
一.因为其定义方式跟我们平时定义方式不同,我们平时写HTML时,是先写标签开头,再写标签的属性.如<table borderwidth="0">,然而我们在使用上面几个方法时,需要有先后顺序,我们需要先定义标签的属性和样式,然后再输出标签头.
二.标签头和尾,需一一对应.可以理解为嵌套关系.最好的理解方法就是输出代码后,查看源文件,再结合原来定义的代码来看.
System.Web.UI.LiteralControl (生成的代码中的空格)
表示 HTML 元素、文本和 ASP.NET 页中不需要在服务器上处理的任何其他字符串。
ASP.NET 将所有不需要服务器端处理的 HTML 元素和可读文本编译为该类的实例。例如,在开始标记中不包含 runat="server" 属性/值对的 HTML 元素将被编译为 LiteralControl 对象。LiteralControl 对象不维护视图状态,因此必须针对每个请求重新创建 LiteralControl 对象的内容。
文本控件的行为与文本容纳器一样,这意味着可以从文本控件提取文本,并通过父服务器控件的 Controls 属性从父服务器控件的 ControlCollection 集合中移除文本控件。因此,当开发从 LiteralControl 类派生的自定义控件时,确保由控件自己执行任何所需的预处理步骤,而不是使用对 LiteralControl..::.Render 方法的调用来完成这些操作。通常,都会这样做以提高 Web 应用程序的响应时间。
可以以编程方式分别使用 ControlCollection..::.Add 或 ControlCollection..::.Remove 方法,从页或服务器控件添加或移除文本控件。
我们还是先来看看与Render方法相关的两个方法
//RenderControl方法的基本实现
public void RenderControl(HtmlTextWriter writer)
{
if(Visible)
{
Render(writer);
}
}
//Render方法基本实现
protected virtual void Render(HtmlTextWriter writer)
{
RenderChildren(writer);
}
//RenderChildren方式基本实现
RenderChildren方法则判断当前控件是否有子控件,如果有,则根据RenderControl方法判断控件的Visible值来呈现控件.所以大家在重写Render方法时,不重写基类Render方法时,将无法实现RenderChildren方法.带来的后果将是无法呈现子控件.
protected virtual void RenderChildren(HtmlTextWriter writer)
{
foreach (Control c in Controls)
{
c.RenderControl(writer);
}
}
IPostBackEventHandler 接口
定义 ASP.NET 服务器控件为处理回发事件而必须实现的方法。
若要创建从浏览器捕获窗体提交信息的服务器控件,必须实现此接口。
下面的代码示例定义一个自定义按钮服务器控件,该控件可引起回发,使用 RaisePostBackEvent 方法捕获回发,并在服务器上引发 Click 事件。
Visual Basic 复制代码
Imports System
Imports System.Web.UI
Imports System.Collections
Imports System.Collections.Specialized
Namespace CustomControls
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> Public Class MyButton
Inherits Control
Implements IPostBackEventHandler
' Define the Click event.
Public Event Click As EventHandler
' Invoke delegates registered with the Click event.
Protected Overridable Sub OnClick(e As EventArgs)
RaiseEvent Click(Me, e)
End Sub
' Define the method of IPostBackEventHandler that raises change events.
Public Sub RaisePostBackEvent(eventArgument As String) _
Implements IPostBackEventHandler.RaisePostBackEvent
OnClick(New EventArgs())
End Sub
Protected Overrides Sub Render(output As HtmlTextWriter)
output.Write("<INPUT TYPE = submit name = " & Me.UniqueID & _
" Value = 'Click Me' />")
End Sub
End Class
End Namespace
C# 复制代码
using System;
using System.Web.UI;
using System.Collections;
using System.Collections.Specialized;
namespace CustomControls {
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public class MyButton: Control, IPostBackEventHandler {
// Defines the Click event.
public event EventHandler Click;
//Invoke delegates registered with the Click event.
protected virtual void OnClick(EventArgs e) {
if (Click != null) {
Click(this, e);
}
}
// Define the method of IPostBackEventHandler that raises change events.
public void RaisePostBackEvent(string eventArgument){
OnClick(new EventArgs());//EventArgs.Empty表示没有事件数据的事件
//EventArgs.Empty等同于EventArgs类的构造函数,等同于new EventArgs()
}
protected override void Render(HtmlTextWriter output) {
output.Write("<INPUT TYPE = submit name = " + this.UniqueID +
" Value = 'Click Me' />");
//为表单元素定义UniqueID,以与IPostBackEventHandler服务器控件的UniqueID相对应
}
}
}
UniqueId 类
为 GUID 优化的唯一标识符。
public UniqueId()
使用新的唯一 GUID 创建此类的新实例。
假设你在页面上多次使用这个控件,编译器将为每个事件委托实例生成一个字段。如果事件的数目很大,则一个委托一个字段的存储成本可能无法接受。.所以推荐采用另外一种优化的事件实现
EventHandlerList 类提供一个简单的委托列表来添加和删除委托,下面来看看更改后的代码,
IPostBackEventHandler接口专门定义了处理回发事件的方法,说白了就是onclick事件,如果自定义控件需要处理回发事件,你就需要继承IPostBackEventHandler接口,然后实现接口的RaisePostBackEvent 方法,另外一个简单的方法就是直接继承Button控件就可以了.
void RaisePostBackEvent(
string eventArgument
)
eventArgument
类型:System..::.String
表示要传递到事件处理程序的可选事件参数的 String。
该页将 eventArgument 参数的值传递给实现 IPostBackEventHandler 接口的控件的 RaisePostBackEvent 方法。此控件还会呈现导致发生回发的 HTML 元素。如果控件呈现了用于回发的客户端脚本,则会在 eventArgument 参数中传递脚本中的参数。如果回发是由简单提交操作所引起的,则 eventArgument 参数为 nullNothingnullptrnull 引用(在 Visual Basic 中为 Nothing)。
在asp.net2.0中,button控件多了一个UseSubmitBehavior 属性,指示 Button 控件使用客户端浏览器的提交机制(客户端回发)还是 ASP.NET 回发机制,默认采用回发机制,如果设置为false的话,则需要调用GetPostBackEventReference 方法来返回 Button 的客户端回发事件
当设置UseSubmitBehavior 属性为flase时,你运行页面时,则会发现一段自动生成的javascript代码
<script type="text/javascript">
//<![CDATA[
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>
IPostBackDataHandler 接口
定义 ASP.NET 服务器控件为自动加载回发数据而必须实现的方法。
LoadPostData 方法 根据服务器控件的状态由于回发而发生更改做出判断是否调用RaisePostDataChangedEvent 方法,返回true则调用(就是旧值和新值不同的时候)
RaisePostDataChangedEvent 方法用于引发任何更改事件
web服务器控件分为HTML服务器控件(如<input id="Button2" runat="server" type="button" value="button" />这样的形式)和标准服务器控件(就是<asp:.. id="" runat="server" />这样的形式的控件)
HTML服务器控件的控件从System.Web.UI.HtmlControls.HtmlControl 类派生
标准服务器控件的控件从System.Web.UI.WebControls.WebControl 类派生
HtmlControl 类和WebControl 类则从System.Web.UI.Control 类派生,并扩展.
WebControl 类提供所有 Web 服务器控件的公共属性、方法和事件。通过设置在此类中定义的属性,可以控制 Web 服务器控件的外观和行为。例如,通过使用 BackColor 和 ForeColor 属性,可以分别控制控件的背景色和字体颜色。在可以显示边框的控件上,可以通过设置 BorderWidth、BorderStyle 和 BorderColor 属性,控制边框宽度、边框样式和边框颜色。Web 服务器控件的大小可以通过 Height 和 Width 属性来指定。
控件的行为可以通过设置某些属性来指定。通过设置 Enabled 属性,可以启用和禁用控件。通过设置 TabIndex 属性,可以控制控件在 Tab 键顺序中的位置。通过设置 ToolTip 属性,可以为控件指定工具提示。
最后总结下:
1.控件继承自WebControl类 主要原因是WebControl类公共的东西比Control类
2.TagKey 表示控件的标签,默认情况下为<span>,可以重写此属性修改或者重写WebControl类的构造函数
3.AddAttributesToRender方法 为标签添加属性和样式
4.RenderContents方法 在标签内呈现内容
如果控件不复杂,则可直接从标准控件继承(如label),再根据需要扩展,重写AddAttributesToRender方法,还可以重写
TagKey更改默认标签,而无须重写RenderContents方法.如果控件比较复杂,不是单一的,则需要在RenderContents方法输出控件的内部的内容.
其实最大的区别就是默认情况下WebControl类为你加了一个标签,方便添加WebControl类的一些公共的东西,如果你重写Render()方法,而舍弃RenderContents方法,你就无福享受WebControl类给你提供的这么多属性和方法了.
WebControl..::.AddAttributesToRender 方法
将需要呈现的 HTML 属性和样式添加到指定的 HtmlTextWriterTag 中。此方法主要由控件开发人员使用。
若要在客户端为 Web 服务器控件呈现属性和样式,通常调用 AddAttribute 和 HtmlTextWriter..::.AddStyleAttribute 方法将每个属性和样式分别插入到 HtmlTextWriter 输出流中。为了简化该过程,此方法为与 Web 服务器控件关联的每个属性和样式封装所有对 HtmlTextWriter..::.AddAttribute 和 HtmlTextWriter..::.AddStyleAttribute 方法的调用。在单个方法调用中,将所有属性和样式插入到 HtmlTextWriter 输出流中。此方法通常由控件开发人员在派生类中重写,以将适当的属性和样式插入到类的 HtmlTextWriter 输出流中。
WebControl..::.RenderContents 方法
将控件的内容呈现到指定的编写器中。此方法主要由控件开发人员使用。
重写 RenderContents 方法以呈现开始和结束标记之间的控件内容。此方法的默认实现会呈现所有子控件。
@ Register
assembly
与 tagprefix 属性关联的命名空间所驻留的程序集。
注意:
程序集名称不能包括文件扩展名。另请注意,如果 assembly 属性丢失,ASP.NET 分析器会假定应用程序的 App_Code 文件夹中存在源代码。如果您希望在页面上注册控件的源代码而不对其进行编译,请将源代码放在 App_Code 文件夹中。ASP.NET 在运行时动态编译 App_Code 文件夹中的源文件。
namespace
正在注册的自定义控件的命名空间。
src
与 tagprefix:tagname 对关联的声明性 ASP.NET 用户控件 文件的位置(相对的或绝对的)。
tagname
与类关联的任意别名。此属性只用于用户控件。
tagprefix
一个任意别名,它提供对包含指令的文件中所使用的标记的命名空间的短引用。
DesignerSerializationVisibility 枚举
指定属性对设计时序列化程序所具有的可见性。
语法
C#
[ComVisibleAttribute(true)]
public enum DesignerSerializationVisibility
成员
成员名称 说明
Hidden 代码生成器不生成对象的代码。
Visible 代码生成器生成对象的代码。
Content 代码生成器产生对象内容的代码,而不是对象本身的代码。
可视化设计器使用 DesignerSerializationVisibility 值指示应检查和保存属性或事件的哪些方面。
//这里要加入元数据[DesignerSerializationVisibility] 就是为了实现在后台实现可以提示复合属性的特点。
[Description("地址集合")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public Address CustomAddress
{
get
{
return address;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]这个是实现属性面板折叠效果的。
TypeConverter 类 提供一种将值的类型转换为其他类型以及访问标准值和子属性的统一方法。
实现转换器 (ExpandableObjectConverter) 的类必须从 TypeConverter 类继承。
[NotifyParentProperty(true)]这个可以实现复合属性的子属性在属性面板中编辑有效!!
[PersistenceMode(PersistenceMode.InnerProperty)]这个可以实现内嵌属性
如 <custom:custom id="Custom1" runat="server" name="Clingingboy" CustomMetier="教师" Age="21">
<CustomAddress City="杭州" Street="不告诉你" State="中国" Zip="310000" />
</custom:custom>
[ParseChildren(true)]
[PersistChildren(false)]这2个用于属性面板中的 内嵌属性的修改 使得它可以被修改
myStyle.BackColor = System.Drawing.Color.Red;
Button1.ApplyStyle(myStyle);
定义方法有通用性,你可以定义一种样式,然后利用控件的ApplyStyle方法来引用样式.给样式编程提供了方面
TableStyle 类用于表示表控件的样式。它封装控制表外观的属性,并可应用于多个表控件以提供通用外观。
通过设置 BackImageUrl 属性,可以指定在表的背景中显示的图像。表的单元格之间的间距量由 CellSpacing 属性控制。单元格内容和单元格边框之间的间距用 CellPadding 属性来指定。通过设置 GridLines 属性,可以指定是否显示单元格边框。表相对于 Web 窗体页上其他元素的水平对齐方式由 HorizontalAlign 属性指示。
WebControl..ControlStyle 属性
获取 Web 服务器控件的样式。
[BrowsableAttribute(false)]
public Style ControlStyle { get; }
类型:System.Web.UI.WebControls..::.Style
Style,它封装 Web 服务器控件的外观属性。
备注
ControlStyle 属性封装 WebControl 类的所有属性,该类指定控件的外观,如 BorderColor 和 Font。
CreateControlStyle 方法用于创建在内部用来实现所有与样式有关的属性的样式对象。派生类可以重写此方法以创建适合该类的样式。此方法主要由控件开发人员使用。
注意:控件开发人员应返回一个 Style,它是从基本控件返回的 Style 派生的。不能假定 ControlStyle 是特定的样式类型,因为派生的控件可能返回不同的类型。