更新:2007 年 11 月
本演练演示如何在 ASP.NET 2.0 版中创建简单的数据绑定 Web 服务器控件。在 ASP.NET 2.0 中,数据源模型使您能够将数据绑定控件绑定到数据源控件,从而允许将常规数据操作(如分页、排序和删除)从数据绑定控件本身中移出。此数据模型可以为页开发人员提供更灵活的数据绑定控件,并能够提高可重用性。ASP.NET 2.0 数据源模型还支持直接绑定到数据集合对象。有关为 ASP.NET 2.0 数据模型开发自定义数据绑定控件的更多信息,请参见为 ASP.NET 2.0 开发自定义数据绑定 Web 服务器控件。
在本演练中,您将创建可以绑定到数据源控件的或实现 IEnumerable 接口的任何对象的数据绑定控件。
本演练涉及以下任务:
创建网站以使用动态编译测试自定义数据绑定控件。
创建扩展基类 DataBoundControl 的数据绑定控件类。此类显示代表绑定数据的表列。下文提供了数据绑定控件类必须提供的内容的概述:
对数据绑定控件基类的 PerformSelect 方法的重写。在此方法内执行任务以启动数据检索。
包含用于接收返回数据的 IEnumerable 类型的单个参数的方法。在此方法内执行任何可能需要的数据处理。最后一步,调用 PerformDataBinding 方法以启动数据绑定。
对 PerformDataBinding 方法的重写。在此方法内枚举检索的数据并添加子控件以代表该数据。
在 Web.config 文件中注册控件。
在 ASP.NET 网页中测试控件。
编译控件以便将其作为二进制代码分发。
测试编译的自定义数据绑定服务器控件。
创建网站以测试控件
可以使用 ASP.NET 动态编译在页中测试控件,而无需将控件编译为程序集。ASP.NET 能动态编译 ASP.NET 网站根目录下 App_Code 目录中放置的代码。这样就可以从页访问 App_Code 中源文件中的类,而无需将其手动编译为程序集。
![]() |
---|
App_Code 目录是 ASP.NET 1.0 和 1.1 中所没有的目录。使用 App_Code 目录进行初始控件测试是一个可选步骤。生成服务器控件的主要步骤与早期版本的 ASP.NET 相同,如下一节“将控件编译为程序集”中所述。 |
创建网站以测试自定义数据绑定控件
创建一个名为 ServerControlsTest 的网站。
可以在 IIS 中将该站点创建为名为 ServerControlsTest 的虚拟目录。有关如何创建和配置 IIS 虚拟目录的详细信息,请参见如何:在 IIS 5.0 和 6.0 中创建和配置虚拟目录。
直接在网站的根目录(Web 应用程序根目录)下创建 App_Code 目录。
创建 SimpleDataBoundColumn 类
在本节中,将创建扩展 DataBoundControl 类的数据绑定控件类。这个新控件可在一个单列表中显示绑定数据。
创建 SimpleDataBoundColumn 类
在 App_Code 文件夹下,创建一个名为 SimpleDataBoundColumn.cs 或 SimpleDataBoundColumn.vb 的类。
将以下代码添加到该类文件中:
Imports System Imports System.Collections Imports System.ComponentModel Imports System.Security.Permissions Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Namespace Samples.AspNet.Controls.VB <AspNetHostingPermission(SecurityAction.Demand, _ Level:=AspNetHostingPermissionLevel.Minimal), _ AspNetHostingPermission(SecurityAction.InheritanceDemand, _ Level:=AspNetHostingPermissionLevel.Minimal)> _ Public Class SimpleDataBoundColumn Inherits DataBoundControl Public Property DataTextField() As String Get Dim o As Object = ViewState("DataTextField") If o Is Nothing Then Return String.Empty Else Return CStr(o) End If End Get Set(ByVal value As String) ViewState("DataTextField") = value If (Initialized) Then OnDataPropertyChanged() End If End Set End Property Protected Overrides Sub PerformSelect() ' Call OnDataBinding here if bound to a data source using the ' DataSource property (instead of a DataSourceID), because the ' databinding statement is evaluated before the call to GetData. If Not IsBoundUsingDataSourceID Then OnDataBinding(EventArgs.Empty) End If ' The GetData method retrieves the DataSourceView object from ' the IDataSource associated with the data-bound control. GetData().Select(CreateDataSourceSelectArguments(), _ AddressOf OnDataSourceViewSelectCallback) ' The PerformDataBinding method has completed. RequiresDataBinding = False MarkAsDataBound() ' Raise the DataBound event. OnDataBound(EventArgs.Empty) End Sub Private Sub OnDataSourceViewSelectCallback(ByVal retrievedData As IEnumerable) ' Call OnDataBinding only if it has not already been ' called in the PerformSelect method. If IsBoundUsingDataSourceID Then OnDataBinding(EventArgs.Empty) End If ' The PerformDataBinding method binds the data in the ' retrievedData collection to elements of the data-bound control. PerformDataBinding(retrievedData) End Sub Protected Overrides Sub PerformDataBinding(ByVal retrievedData As IEnumerable) MyBase.PerformDataBinding(retrievedData) ' Verify data exists. If Not (retrievedData Is Nothing) Then Dim tbl As New Table() Dim row As TableRow Dim cell As TableCell Dim dataStr As String = String.Empty Dim dataItem As Object For Each dataItem In retrievedData ' If the DataTextField was specified get the data ' from that field, otherwise get the data from the first field. If DataTextField.Length > 0 Then dataStr = DataBinder.GetPropertyValue(dataItem, DataTextField, Nothing) Else Dim props As PropertyDescriptorCollection = TypeDescriptor.GetProperties(dataItem) If props.Count >= 1 Then If Nothing <> props(0).GetValue(dataItem) Then dataStr = props(0).GetValue(dataItem).ToString() End If End If End If row = New TableRow() tbl.Rows.Add(row) cell = New TableCell() cell.Text = dataStr row.Cells.Add(cell) Next dataItem Controls.Add(tbl) End If End Sub End Class End Namespace
using System; using System.Collections; using System.ComponentModel; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace Samples.AspNet.Controls.CS { [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class SimpleDataBoundColumn : DataBoundControl { public string DataTextField { get { object o = ViewState["DataTextField"]; return ((o == null) ? string.Empty : (string)o); } set { ViewState["DataTextField"] = value; if (Initialized) { OnDataPropertyChanged(); } } } protected override void PerformSelect() { // Call OnDataBinding here if bound to a data source using the // DataSource property (instead of a DataSourceID), because the // databinding statement is evaluated before the call to GetData. if (!IsBoundUsingDataSourceID) { this.OnDataBinding(EventArgs.Empty); } // The GetData method retrieves the DataSourceView object from // the IDataSource associated with the data-bound control. GetData().Select(CreateDataSourceSelectArguments(), this.OnDataSourceViewSelectCallback); // The PerformDataBinding method has completed. RequiresDataBinding = false; MarkAsDataBound(); // Raise the DataBound event. OnDataBound(EventArgs.Empty); } private void OnDataSourceViewSelectCallback(IEnumerable retrievedData) { // Call OnDataBinding only if it has not already been // called in the PerformSelect method. if (IsBoundUsingDataSourceID) { OnDataBinding(EventArgs.Empty); } // The PerformDataBinding method binds the data in the // retrievedData collection to elements of the data-bound control. PerformDataBinding(retrievedData); } protected override void PerformDataBinding(IEnumerable retrievedData) { base.PerformDataBinding(retrievedData); // Verify data exists. if (retrievedData != null) { Table tbl = new Table(); TableRow row; TableCell cell; string dataStr = String.Empty; foreach (object dataItem in retrievedData) { // If the DataTextField was specified get the data // from that field, otherwise get the data from the first field. if (DataTextField.Length > 0) { dataStr = DataBinder.GetPropertyValue(dataItem, DataTextField, null); } else { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(dataItem); if (props.Count >= 1) { if (null != props[0].GetValue(dataItem)) { dataStr = props[0].GetValue(dataItem).ToString(); } } } row = new TableRow(); tbl.Rows.Add(row); cell = new TableCell(); cell.Text = dataStr; row.Cells.Add(cell); } this.Controls.Add(tbl); } } } }
代码讨论
SimpleDataBoundColumn 类是从数据绑定基类 DataBoundControl 派生的。从此基类派生可以提供公开的 DataSourceID、DataSource 和 DataMember 数据绑定属性。通过这些公开的属性,页开发人员可以指定数据源以及要绑定到此自定义控件的特定数据成员。
为了说明如何添加其他自定义数据绑定属性,已将 DataTextField 属性添加到 SimpleDataBoundColumn 类。当页开发人员设置了 DataTextField 属性后,新值将存储在视图状态中。如果已对控件进行了初始化,则还会调用 OnDataPropertyChanged 方法。这可以强制数据绑定控件重新绑定数据,以便控件能够使用新的数据绑定属性设置。
重写的 DataBind 方法是必需的,并且它包含对关联数据源中的对象进行枚举以及创建子控件的逻辑。以下任务必须在 ASP.NET 2.0 数据绑定控件中和在重写 DataBind 方法中执行,如 SimpleDataBoundColumn 类中所演示:
在 IsBoundUsingDataSourceID 属性中检查 false 的值以确定是否在 DataSource 属性中指定了数据源。
如果在 DataSource 属性中指定了要绑定的数据,则调用 OnDataBinding 方法以绑定在 DataSource 属性中指定的数据成员。
调用 GetData 方法以检索与数据绑定控件关联的 DataSourceView 对象。
调用检索的 DataSourceView 对象的 Select 方法以启动数据检索并指定将处理检索的数据的 OnDataSourceViewSelectCallback 回调方法。
为了指示 PerformSelect 方法的数据检索任务已完成,会将 RequiresDataBinding 属性设置为 false 并调用 MarkAsDataBound 方法。
引发 OnDataBound 事件。
OnDataSourceViewSelectCallback 回调方法接收检索的数据。此回调方法必须接受 IEnumerable 类型的单个参数。如果自定义控件需要,在此应进行任何数据处理。此自定义控件按原样使用原始数据。因此,在本示例中没有进行其他数据处理。最后一步,调用 PerformDataBinding 方法以启动数据绑定过程。
在 PerformDataBinding 方法的重写内,创建将代表该数据的所有子控件。枚举数据集合,并为每个数据项创建新的 TableCell 对象。如果设置了 DataTextField 属性,则该属性用于确定哪个数据字段绑定到单元格的 Text 属性。若未设置,则使用第一个字段。
将 Table 父控件添加到自定义 SimpleDataBoundColumn 控件的 Controls 集合。当执行继承的 Render 方法时,会自动呈现添加到控件的 Controls 集合的任何控件。
有关数据绑定 Web 服务器控件所需实现的更多信息,请参见为 ASP.NET 2.0 开发自定义数据绑定 Web 服务器控件。
创建标记前缀
标记前缀是指在页中以声明方式创建控件时出现在控件类型名称前面的前缀,如 <asp:Table /> 中的“asp”。若要在页中以声明方式使用您的控件,则 ASP.NET 需要一个映射到该控件的命名空间的标记前缀。通过在每个使用自定义控件的页上添加一个 @ Register 指令,页开发人员可提供标记前缀/命名空间映射,如以下示例所示:
<%@ Register TagPrefix="aspSample"
Namespace="Samples.AspNet.Controls.CS"%>
<%@ Register TagPrefix="aspSample"
Namespace="Samples.AspNet.Controls.VB"%>
![]() |
---|
请注意,在 @ Register 指令中,没有指定控件程序集的名称的 assembly 属性。如果缺少 assembly 属性,则 ASP.NET 会推断该程序集是从 App_Code 目录中的源文件动态编译而来。 |
除了在每个 .aspx 页中使用 @ Register 指令,页开发人员还可以在 Web.config 文件中指定标记前缀和命名空间映射。如果将在 Web 应用程序的多个页中使用自定义控件,则该方法非常有用。下面的过程描述如何在 Web.config 文件中指定标记前缀映射。
在 Web.config 文件中添加标记前缀映射
如果网站还没有一个名为 Web.config 的文件,则请在网站的根目录中创建此文件。
创建了新的 Web.config 文件之后,将以下 XML 标记复制到该文件中并保存该文件。如果您的站点已具有 Web.config 文件,则将以下突出显示的元素添加到该文件中。
说明:
标记前缀项必须是 controls 节的子项,而该节必须位于 pages 节下,而后者又必须是 system.web 的子项。
<?xml version="1.0"?> <configuration> <system.web> <pages> <controls> <add tagPrefix="aspSample" namespace="Samples.AspNet.Controls.CS" /> </controls> </pages> </system.web> </configuration>
<?xml version="1.0"?> <configuration> <system.web> <pages> <controls> <add tagPrefix="aspSample" namespace="Samples.AspNet.Controls.VB" /> </controls> </pages> </system.web> </configuration>
突出显示部分是一个标记前缀项,该项将标记前缀“aspSample”映射到命名空间 Samples.AspNet.Controls.CS 或 Samples.AspNet.Controls.VB。
在配置文件中指定了标记前缀映射之后,可以在网站的任何页中以声明方式使用 SimpleDataBoundColumn 控件(如 <aspSample:SimpleDataBoundColumn />)。
![]() |
---|
在 ASP.NET 1.0 和 1.1 中,标记前缀映射在每个使用自定义控件的页的 @ Register 指令中指定。 |
创建页以使用自定义数据绑定控件
在此部分的演练中,您将创建使您能够测试自定义数据绑定控件的页标记。
创建使用自定义数据绑定控件的页
在网站中创建名为 TestSimpleDataBoundColumn.aspx 的文件。
将以下标记复制到 TestSimpleDataBoundColumn.aspx 文件中并保存该文件。
<%@ Page Language="VB" Trace="true"%> <%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.Controls.VB" %> <%@ Import Namespace="System.Data" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <script runat="server"> Function CreateDataSource() As ICollection ' Create sample data for the DataList control. Dim dt As DataTable = New DataTable() dim dr As DataRow ' Define the columns of the table. dt.Columns.Add(New DataColumn("IntegerValue", GetType(Int32))) dt.Columns.Add(New DataColumn("StringValue", GetType(String))) dt.Columns.Add(New DataColumn("CurrencyValue", GetType(Double))) dt.Columns.Add(New DataColumn("ImageValue", GetType(String))) ' Populate the table with sample values. Dim i As Integer For i = 0 To 8 dr = dt.NewRow() dr(0) = i dr(1) = "Description for item " & i.ToString() dr(2) = 1.23 * (i + 1) dr(3) = "Image" & i.ToString() & ".jpg" dt.Rows.Add(dr) Next i Dim dv As DataView = New DataView(dt) Return dv End Function Sub Page_Load(sender As Object, e As EventArgs) ' Load sample data only once, when the page is first loaded. If Not IsPostBack Then simpleDataBoundColumn1.DataSource = CreateDataSource() simpleDataBoundColumn1.DataBind() End If End Sub </script> <head runat="server"> <title>SimpleDataBoundColumn test page</title> </head> <body> <form id="form1" runat="server"> <div> <aspSample:SimpleDataBoundColumn runat="server" id="simpleDataBoundColumn1" DataTextField="CurrencyValue" BorderStyle="Solid"></aspSample:SimpleDataBoundColumn> </div> </form> </body> </html>
<%@ Page Language="C#" Trace="true"%> <%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.Controls.CS" %> <%@ Import Namespace="System.Data" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <script runat="server"> ICollection CreateDataSource() { DataTable dt = new DataTable(); DataRow dr; dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32))); dt.Columns.Add(new DataColumn("StringValue", typeof(string))); dt.Columns.Add(new DataColumn("CurrencyValue", typeof(double))); for (int i = 0; i < 9; i++) { dr = dt.NewRow(); dr[0] = i; dr[1] = "Item " + i.ToString(); dr[2] = 1.23 * (i + 1); dt.Rows.Add(dr); } DataView dv = new DataView(dt); return dv; } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { simpleDataBoundColumn1.DataSource = CreateDataSource(); simpleDataBoundColumn1.DataBind(); } } </script> <head runat="server"> <title>SimpleDataBoundColumn test page</title> </head> <body> <form id="form1" runat="server"> <div> <aspSample:SimpleDataBoundColumn runat="server" id="simpleDataBoundColumn1" DataTextField="CurrencyValue" BorderStyle="Solid"></aspSample:SimpleDataBoundColumn> </div> </form> </body> </html>
运行 SimpleDataBoundColumnTest.aspx 页。
对自定义控件的源代码做一些更改。例如,通过在 RenderContents 方法末尾处添加此行代码来多写一个字符串:
writer.Write("<br />Testing how the App_Code directory works.");
writer.Write("<br />Testing how the App_Code directory works.")
在浏览器中刷新 SimpleDataBoundColumnTest.aspx 页。
将看到,尽管没有编译控件,对控件所做的更改仍在页中反映出来了。
将控件编译为程序集
使用 App_Code 目录,您可以直接测试控件,而无需对其进行编译。但是,如果要将控件作为对象代码分发给其他开发人员,则必须对其进行编译。此外,如果没有将控件编译为程序集,就不能将该控件添加到可视化设计器的工具箱中。
将控件编译为程序集
按照以下这些步骤设置计算机的 Windows 环境 PATH 变量,使其包含 .NET Framework 的安装路径:
在 Windows 中,右击**“我的电脑”,选择“属性”,单击“高级”选项卡,然后单击“环境变量”**按钮。
在**“系统变量”**列表中,双击 Path 变量。
在**“变量值”**文本框中,将一个分号 (;) 添加到文本框中的现有值的末尾,然后键入 .NET Framework 的安装路径。.NET Framework 通常安装在位于 \Microsoft.NET\Framework\版本号 的 Windows 安装目录中。
单击**“确定”**关闭每个对话框。
从包含在本演练的先前步骤中创建的源文件的 App_Code 目录运行以下命令。这将在同一个 App_Code 目录中生成名为 Samples.AspNet.Controls.CS.dll 或 Samples.AspNet.Controls.VB.dll 的程序集。
csc /t:library /out:Samples.AspNet.Controls.CS.dll /r:System.dll /r:System.Web.dll *.cs
vbc /t:library /out:Samples.AspNet.Controls.VB.dll /r:System.dll /r:System.Web.dll *.vb
/t:library 编译器选项告知编译器创建一个库,而不是创建一个可执行程序集。/out 选项为程序集提供名称,而 /r 选项则列出链接到您的程序集的那些程序集。
说明:
为保持示例独立,本演练要求创建具有单个控件的程序集。通常,.NET Framework 设计指导原则建议不要创建只包含很少的类的程序集。为了便于部署,应尽可能少地创建程序集。
使用 TagPrefixAttribute 提供标记前缀/命名空间映射
在前面的内容中,您已了解页开发人员如何在页或 Web.config 文件中指定标记前缀。当编译控件时,可以选择通过包含程序集级别的 System.Web.UI.TagPrefixAttribute 属性,建议可视化设计器应为控件使用的默认标记前缀。如果设计器未找到在 Web.config 文件或页中的 @ Register 指令中映射的标记前缀,TagPrefixAttribute 属性就会为可视化设计器提供可以使用的标记前缀,因此该属性非常有用。在工具箱中首次双击控件或将其从工具箱拖动到页中时,此标记前缀将向页进行注册。
如果决定使用 TagPrefixAttribute 属性,则可以在与控件一起编译的单独文件中指定该属性。根据约定,该文件名为 AssemblyInfo.语言扩展,如 AssemblyInfo.cs 或 AssembyInfo.vb。下面的过程介绍如何指定 TagPrefixAttribute 元数据。
![]() |
---|
如果没有在控件的程序集中指定 TagPrefixAttribute,并且页开发人员没有在页或 Web.config 文件中指定标记前缀/命名空间映射,则可视化设计器将创建一个默认的标记前缀。例如,当从工具箱中拖动您的控件时,Visual Studio 2005 将为您的控件创建其自己的控件标记,如 cc1。 |
使用 TagPrefixAttribute 添加标记前缀映射
在源代码目录中创建一个名为 AssemblyInfo.cs 或 AssemblyInfo.vb 的文件并向该文件添加以下代码。
using System; using System.Web.UI; [assembly: TagPrefix("Samples.AspNet.Controls.CS", "aspSample")]
Imports System Imports System.Web.UI <Assembly: TagPrefix("Samples.AspNet.Controls.VB", "aspSample")>
标记前缀属性在命名空间 Samples.AspNet.Controls.CS 或 Samples.AspNet.Controls.VB 与前缀 aspSample 之间创建映射。
使用前面使用的编译命令重新编译所有的源文件(使用或不使用嵌入资源)。
在 ASP.NET 页中使用已编译的自定义数据绑定服务器控件
若要测试自定义控件的已编译版本,则必须使网站中的页可以访问此控件的程序集。
使网站可以访问控件的程序集
在网站的根目录下创建一个 Bin 目录。
将控件程序集(Samples.AspNet.Controls.CS.dll 或 Samples.AspNet.Controls.VB.dll)从 App_Code 目录拖到 Bin 目录中。
从 App_Code 目录中删除该控件的源文件。
如果没有删除源文件,则您的控件的类型将同时存在于编译的程序集中和由 ASP.NET 创建的动态生成的程序集中。这在加载该控件时会造成不明确引用,加载任何使用该控件的页时将生成编译器错误。
本演练中创建的程序集必须放在 ASP.NET 网站的 Bin 目录中才能使网站中的页使用您的控件,故而该程序集称为私有程序集。如果其他应用程序没有安装该程序集的副本,则这些应用程序都不能访问该程序集。如果要为共享的 Web 宿主应用程序创建控件,通常会将控件打包到一个私有程序集中。但是,如果要创建在专用宿主环境中使用的控件,或要创建 ISP 向所有客户提供的一系列控件,则需要将您的控件打包到安装在全局程序集缓存中的一个共享(强名称)程序集中。有关更多信息,请参见使用程序集和全局程序集缓存。
接下来,必须修改在 Web.config 中创建的标记前缀映射,以指定控件的程序集名称。
修改 Web.config 中的标记前缀映射
编辑 Web.config 文件,向 addtagPrefix 元素添加 assembly 属性:
<controls> <add tagPrefix="aspSample" namespace="Samples.AspNet.Controls.CS" assembly="Samples.AspNet.Controls.CS" /> </controls>
<controls> <add tagPrefix="aspSample" namespace="Samples.AspNet.Controls.VB" assembly="Samples.AspNet.Controls.VB" /> </controls>
assembly 属性指定控件所在的程序集的名称。addtagPrefix 元素将标记前缀映射到命名空间和程序集的组合。ASP.NET 从 App_Code 目录中的源文件动态生成程序集时,无需提供程序集属性。未使用程序集属性时,ASP.NET 会从通过 App_Code 目录动态生成的程序集加载控件的类型。
查看使用自定义控件的页
通过在地址栏中输入以下 URL 在浏览器中显示 SimpleDataBoundColumnTest.aspx 页:
https://localhost/ServerControlsTest/SimpleDataBoundColumnTest.aspx
如果您在可视化设计器(如 Visual Studio 2005)中使用您的控件,则您可以将您的控件添加到工具箱中,可将该控件从工具箱拖到设计图面,还可在属性浏览器中访问该控件的属性和事件。此外,在 Visual Studio 2005 中,您的控件在网页设计器的“源”视图和代码编辑器中具有完整的 IntelliSense 支持。这包括 script 块中的语句结束支持以及页开发人员单击控件标记时的属性浏览器支持。
![]() |
---|
在许多可视化设计器中,可以将自定义控件添加到设计器的工具箱中。有关详细信息,请参阅设计器文档。 |
后续步骤
该简单的自定义数据绑定服务器控件演示用于创建自定义控件的基本步骤,此自定义控件能够为页开发人员提供将其绑定到外部数据源的标准、有效和灵活的方法。您可以从此处着手研究 Visual Studio 中提供的框架,以帮助您创建复杂的自定义服务器控件。建议进一步研究的方面包括:
查看对特定于开发自定义数据绑定服务器控件的通用结构和实现的介绍。有关详细信息,请参见为 ASP.NET 2.0 开发自定义数据绑定 Web 服务器控件。
调查您可以扩展和自定义的现有数据绑定服务器控件。有关可用的数据绑定 Web 服务器控件的概述,请参见 ASP.NET 数据绑定 Web 服务器控件概述。有关数据绑定 Web 服务器控件类的信息,请参见下列参考主题:GridView、DetailsView、FormView、Repeater 和 DataList。
了解有关呈现、定义属性、保持状态和实现自定义复合控件的更多信息。有关详细信息,请参见开发自定义 ASP.NET 服务器控件、控件状态与视图状态示例和服务器控件自定义状态管理。
了解可以应用于自定义数据绑定服务器控件及其成员以提供设计工具所用信息的元数据属性。有关详细信息,请参见自定义服务器控件的元数据属性。
创建用于添加设计时功能、模板或样式的控件设计器。有关自定义数据绑定控件设计器的示例,请参见 HierarchicalDataBoundControlDesigner 和演练:为 Web 服务器控件创建基本控件设计器。有关 ASP.NET 控件设计器的概述,请参见 ASP.NET 控件设计器概述。
使用自定义数据绑定控件设计器的示例。有关详细信息,请参见 HierarchicalDataBoundControlDesigner 类。
研究有关定义合适的设计时属性以使自定义服务器控件在 Visual Studio 工具箱中可用的演示。有关详细信息,请参见如何:在 Visual Studio 中使用自定义 ASP.NET 服务器控件。
请参见
任务
概念
为 ASP.NET 2.0 开发自定义数据绑定 Web 服务器控件
参考
HierarchicalDataBoundControlDesigner