开始创作您自己的 ASP.NET 服务器控件很容易。创建简单的自定义控件时,您所要做的只是定义从 System.Web.UI.Control 派生的类并重写它的 Render 方法。Render 方法采用 System.Web.UI.HtmlTextWriter 类型的参数。控件要发送到客户端的 HTML 作为字符串参数传递到 HtmlTextWriter 的 Write 方法。
2。定义简单属性
属性类似具有访问器方法的“聪明”字段。应该从控件公开属性而不是公开公共字段,因为属性允许数据隐藏、可以版本化并受可视化设计器的支持。属性具有设置和检索属性的 get/set 访问器方法,并允许在需要时执行附加的程序逻辑。
3。义类属性
如果 A 类具有一个类型为 B 类的属性,则 B 的属性(如果有)称为 A 的子属性。
注意 ASP.NET 具有设置子属性的特殊语法。下面的代码示例显示如何以声明方式设置 SimpleSubProperty
上的 Format.Color
和 Format.Size
子属性。“-”语法指示子属性。
<SimpleControlSamples:SimpleSubProperty Message="Hello There" Format-Color="red" Format-Size="3" runat=server/>
4。检索内部内容
每个控件都具有从 System.Web.UI.Control 继承的 Controls 属性。这是表示控件的子控件(如果有)的集合属性。如果控件未用 ParseChildrenAttribute 标记,或是标记为 ParseChildrenAttribute(ChildrenAsProperties = false),则当控件在页上以声明方式使用时,ASP.NET 页框架将应用以下分析逻辑。如果分析器在控件的标记内遇到嵌套控件,它将创建嵌套控件的实例并将它们添加到控件的 Controls 属性。标记之间的文本添加为 LiteralControl。任何其他嵌套元素都生成分析器错误
注意:如果自定义控件是从 WebControl 派生的,它将不具有示例中描述的分析逻辑,因为 WebControl 是用 ParseChildrenAttribute(ChildrenAsProperties = true) 标记的,这导致不同的分析逻辑。有关 ParseChildrenAttribute 的更多信息,请参阅 SDK 文档。
5。开发复合控件
可以通过使用类撰写组合现有控件来创作新控件。复合控件等效于使用 ASP.NET 页语法创作的用户控件。用户控件和复合控件之间的主要差异是用户控件保持为 .ascx 文本文件,而复合控件则经过编译并保持在程序集中。
开发复合控件的主要步骤是:
- 重写从 Control 继承的受保护的 CreateChildControls 方法,以创建子控件的实例并将它们添加到控件集合。
- 如果复合控件的新实例将在页上重复创建,请实现 System.Web.UI.INamingContainer 接口。这是不具有方法的标记接口。当用控件实现时,ASP.NET 页框架将在此控件下创建新的命名范围。这确保了子控件在控件层次结构树中具有唯一的 ID。
因为子控件会提供呈现逻辑,所以不必重写 Render 方法。可以公开合成子控件属性的属性。
6。在复合控件中处理事件
复合控件可以处理其子控件引发的事件。这通过提供事件处理方法,并将委托附加到子控件引发的事件来完成
7。从复合控件引发自定义事件
复合控件可以定义自定义事件,通过引发该事件来响应其子控件引发的事件。
实现方法如下:
- 自定义
Change
事件通过标准事件模式定义。(该模式包括受保护的 OnChange
方法的定义,该方法将引发 Change
事件。)
public event EventHandler Change;
protected void OnChange(EventArgs e) {
Change(this, e);
}
- 为 TextBox 的 TextChanged 事件定义了一个事件处理方法。该方法通过调用
OnChange
方法来引发 Change
事件。
private void TextBox_Change(Object sender, EventArgs e) {
OnChange(EventArgs.Empty);
}
- CreateChildControls 方法创建一个事件处理程序的实例,该实例引用上述方法并将事件处理程序附加到 TextBox 实例的 TextChanged 事件。
protected override void CreateChildControls() {
..
TextBox box = new TextBox();
box.TextChanged += new EventHandler(this.TextBox_Change);
...
}
- Change 事件可以由承载控件的页来处理
7。维护状态
每个 Web 窗体控件都有一个 State 属性(从 Control 继承),该属性使 Web 窗体控件能够参与 State 管理。State 的类型为 Sytem.Web.UI.StateBag,这是等效于哈希表的数据结构。控件可以将数据作为键/值对保存在 State 中。State 通过 ASP.NET 页框架保持为字符串变量,并以隐藏变量的形式与客户端之间往返。回发时,页框架分析来自隐藏变量的输入字符串,并在页的控件层次结构中填充每个控件的 State 属性。通过使用 State 属性,控件可以还原其状态(将属性和字段设置为它们回发前的值)。控件开发人员应该知道通过往返行程将数据发送到客户端存在性能开销,并且应该明白他们在 State 中保存的内容。
8。开发处理回发数据的自定义(非复合)控件
您在本“入门”开始时创作了简单的自定义控件。下面的示例说明一个做更有意义的事情的自定义控件——它呈现输入框,并读入用户输入的数据。检查回发(输入)数据的控件必须实现 System.Web.UI.IPostBackDataHandler 接口。这将向 ASP.NET 页框架发出信号,指出控件应参与回发数据处理。页框架将输入数据作为键/值对传递给此接口的 LoadPostData 方法。在此方法的实现中,控件可以像下面这样检查输入数据并更新其属性。
9。为自定义回发生成客户端 JavaScript
如果控件要捕获回发事件(来自客户端的窗体提交),它必须实现 System.Web.UI.IPostBackEventHandler 接口。此接口向 ASP.NET 页框架发出信号,指出控件希望收到回发事件通知。RaisePostBackEvent 方法允许控件处理该事件和引发其他事件。另外,ASP.NET 页框架具有自定义事件结构,该结构允许控件生成启动自定义回发的客户端 JavaScript。回发通常仅由几个元素启动,如 Submit(提交)按钮或 Image(图像)按钮。不过,通过发出客户端 JavaScript,控件也可以从其他 HTML 元素启动回发。
10。开发模板控件
ASP.NET 页框架允许控件开发人员通过使用模板创作将用户界面同控件逻辑分开的控件。通过将 UI 提供为模板标记之间的参数,页面开发人员可以自定义控件的显示。
模板控件具有一个或多个类型为 System.Web.UI.ITemplate 的属性,
[TemplateContainer(typeof(Template1))] public ITemplate MessageTemplate {...}
属性(以上方括号中的)指定容器(父)控件的类型。 ITemplate 接口具有一个方法 InstantiateIn,该方法动态创建控件实例。这在 CreateChildControls 方法中的 ITemplate 属性上调用,如下面的示例所示。
ITemplate 接口具有一个方法 InstantiateIn,该方法动态创建控件实例。这在 CreateChildControls 方法中的 ITemplate 属性上调用,如下面的示例所示。
protected override void CreateChildControls() {
if (MessageTemplate != null) {
MessageTemplate.InstantiateIn(this);
}
...
}
11。开发模板数据绑定控件
12。重写控件分析
正如在检索内部内容中看到的,如果控件 A 在页上的其控件标记中有嵌套控件,页分析器会将那些控件的实例添加到 A 的 Controls 集合。这通过调用 A 的 AddSubParsedObject 方法来实现。每个控件从 Control 继承此方法,默认实现只不过将子控件插入到控件层次结构树中。通过重写 AddSubParsedObject 方法,控件可以重写默认的分析逻辑。
注意:如果自定义控件是从 WebControl 派生的,它将不具有示例中描述的分析逻辑,因为 WebControl 是用 ParseChildrenAttribute(ChildrenAsProperties = true) 标记的,这导致不同的分析逻辑。有关 ParseChildrenAttribute 的更多信息,请参阅 SDK 文档。检索内部内容主题也更详尽地说明了此问题。
13。定义自定义控件生成器
ASP.NET 页框架使用称为控件生成器的类来处理页上控件标记中的声明。每个 Web 窗体控件都与默认的控件生成器类 System.Web.UI.ControlBuilder 关联。默认的控件生成器为它在控件标记中遇到的每个嵌套控件将子控件添加到 Controls 集合。另外,它为嵌套控件标记之间的文本添加 Literal 控件。通过将自定义控件生成器类与控件关联,可以重写此默认行为。这通过对控件应用控件生成器属性来实现,如下面的示例所示。
[ControlBuilderAttribute(typeof(CustomParse2ControlBuilder))]
public class CustomParse2 : Control {...}
以上方括号里的元素为公共语言运行库属性,该属性将 CustomParse2ControlBuilder
类与 CustomParse2
控件关联。通过从 ControlBuilder 派生并重写其方法,可以定义您自己的自定义控件生成器。
可以通过使用类撰写组合现有控件来创作新控件。复合控件等效于使用 ASP.NET 页语法创作的用户控件。用户控件和复合控件之间的主要差异是用户控件保持为 .ascx 文本文件,而复合控件则经过编译并保持在程序集中。
开发复合控件的主要步骤是:
- 重写从 Control 继承的受保护的 CreateChildControls 方法,以创建子控件的实例并将它们添加到控件集合。
- 如果复合控件的新实例将在页上重复创建,请实现 System.Web.UI.INamingContainer 接口。这是不具有方法的标记接口。当用控件实现时,ASP.NET 页框架将在此控件下创建新的命名范围。这确保了子控件在控件层次结构树中具有唯一的 ID。
因为子控件会提供呈现逻辑,所以不必重写 Render 方法。可以公开合成子控件属性的属性。
6。在复合控件中处理事件
复合控件可以处理其子控件引发的事件。这通过提供事件处理方法,并将委托附加到子控件引发的事件来完成
7。从复合控件引发自定义事件
复合控件可以定义自定义事件,通过引发该事件来响应其子控件引发的事件。
实现方法如下:
- 自定义
Change
事件通过标准事件模式定义。(该模式包括受保护的OnChange
方法的定义,该方法将引发Change
事件。)
public event EventHandler Change;
protected void OnChange(EventArgs e) {
Change(this, e);
}
- 为 TextBox 的 TextChanged 事件定义了一个事件处理方法。该方法通过调用
OnChange
方法来引发Change
事件。
private void TextBox_Change(Object sender, EventArgs e) {
OnChange(EventArgs.Empty);
}
- CreateChildControls 方法创建一个事件处理程序的实例,该实例引用上述方法并将事件处理程序附加到 TextBox 实例的 TextChanged 事件。
protected override void CreateChildControls() {
..
TextBox box = new TextBox();
box.TextChanged += new EventHandler(this.TextBox_Change);
...
}
- Change 事件可以由承载控件的页来处理
7。维护状态
每个 Web 窗体控件都有一个 State 属性(从 Control 继承),该属性使 Web 窗体控件能够参与 State 管理。State 的类型为 Sytem.Web.UI.StateBag,这是等效于哈希表的数据结构。控件可以将数据作为键/值对保存在 State 中。State 通过 ASP.NET 页框架保持为字符串变量,并以隐藏变量的形式与客户端之间往返。回发时,页框架分析来自隐藏变量的输入字符串,并在页的控件层次结构中填充每个控件的 State 属性。通过使用 State 属性,控件可以还原其状态(将属性和字段设置为它们回发前的值)。控件开发人员应该知道通过往返行程将数据发送到客户端存在性能开销,并且应该明白他们在 State 中保存的内容。
8。开发处理回发数据的自定义(非复合)控件
您在本“入门”开始时创作了简单的自定义控件。下面的示例说明一个做更有意义的事情的自定义控件——它呈现输入框,并读入用户输入的数据。检查回发(输入)数据的控件必须实现 System.Web.UI.IPostBackDataHandler 接口。这将向 ASP.NET 页框架发出信号,指出控件应参与回发数据处理。页框架将输入数据作为键/值对传递给此接口的 LoadPostData 方法。在此方法的实现中,控件可以像下面这样检查输入数据并更新其属性。
9。为自定义回发生成客户端 JavaScript
如果控件要捕获回发事件(来自客户端的窗体提交),它必须实现 System.Web.UI.IPostBackEventHandler 接口。此接口向 ASP.NET 页框架发出信号,指出控件希望收到回发事件通知。RaisePostBackEvent 方法允许控件处理该事件和引发其他事件。另外,ASP.NET 页框架具有自定义事件结构,该结构允许控件生成启动自定义回发的客户端 JavaScript。回发通常仅由几个元素启动,如 Submit(提交)按钮或 Image(图像)按钮。不过,通过发出客户端 JavaScript,控件也可以从其他 HTML 元素启动回发。
10。开发模板控件
ASP.NET 页框架允许控件开发人员通过使用模板创作将用户界面同控件逻辑分开的控件。通过将 UI 提供为模板标记之间的参数,页面开发人员可以自定义控件的显示。
模板控件具有一个或多个类型为 System.Web.UI.ITemplate 的属性,
[TemplateContainer(typeof(Template1))] public ITemplate MessageTemplate {...}
属性(以上方括号中的)指定容器(父)控件的类型。 ITemplate 接口具有一个方法 InstantiateIn,该方法动态创建控件实例。这在 CreateChildControls 方法中的 ITemplate 属性上调用,如下面的示例所示。
ITemplate 接口具有一个方法 InstantiateIn,该方法动态创建控件实例。这在 CreateChildControls 方法中的 ITemplate 属性上调用,如下面的示例所示。
protected override void CreateChildControls() {
if (MessageTemplate != null) {
MessageTemplate.InstantiateIn(this);
}
...
}
11。开发模板数据绑定控件
12。重写控件分析
正如在检索内部内容中看到的,如果控件 A 在页上的其控件标记中有嵌套控件,页分析器会将那些控件的实例添加到 A 的 Controls 集合。这通过调用 A 的 AddSubParsedObject 方法来实现。每个控件从 Control 继承此方法,默认实现只不过将子控件插入到控件层次结构树中。通过重写 AddSubParsedObject 方法,控件可以重写默认的分析逻辑。
注意:如果自定义控件是从 WebControl 派生的,它将不具有示例中描述的分析逻辑,因为 WebControl 是用 ParseChildrenAttribute(ChildrenAsProperties = true) 标记的,这导致不同的分析逻辑。有关 ParseChildrenAttribute 的更多信息,请参阅 SDK 文档。检索内部内容主题也更详尽地说明了此问题。
13。定义自定义控件生成器
ASP.NET 页框架使用称为控件生成器的类来处理页上控件标记中的声明。每个 Web 窗体控件都与默认的控件生成器类 System.Web.UI.ControlBuilder 关联。默认的控件生成器为它在控件标记中遇到的每个嵌套控件将子控件添加到 Controls 集合。另外,它为嵌套控件标记之间的文本添加 Literal 控件。通过将自定义控件生成器类与控件关联,可以重写此默认行为。这通过对控件应用控件生成器属性来实现,如下面的示例所示。
[ControlBuilderAttribute(typeof(CustomParse2ControlBuilder))]
public class CustomParse2 : Control {...}
以上方括号里的元素为公共语言运行库属性,该属性将 CustomParse2ControlBuilder
类与 CustomParse2
控件关联。通过从 ControlBuilder 派生并重写其方法,可以定义您自己的自定义控件生成器。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=530217