如何:在动态数据控件中自定义数据字段的外观和行为
更新:2007 年 11 月
ASP.NET 动态数据使用字段模板呈现表中的每个数据字段。字段模板通常为映射到公共语言运行时 (CLR) 数据类型的用户控件(.ascx 文件),该数据类型由数据库数据类型确定。通常,ASP.NET 动态数据提供一个用户控件用于显示每个类型的数据,提供另一个用户控件用于修改或插入该类型的数据。
本主题介绍如何在动态数据控件(例如 DynamicControl 控件和 DynamicField 字段)中,通过设置 UIHint 属性来自定义数据字段的外观和行为。UIHint 属性指定在使用其中一个对象呈现特定数据字段时使用哪个字段模板。UIHint 属性可以指向提供的模板之一,或者指向一个新建的模板。如果不使用动态数据自动创建的页面,而是亲自创建自定义网页来显示和编辑数据,此方法很有用。
或者,可以使用属性在整个应用程序中更改数据字段的显示和外观。有关更多信息,请参见如何:在数据模型中自定义数据字段的外观和行为。
在数据绑定控件中自定义数据字段的外观和行为
(可选)创建一个自定义字段模板,为数据模型中特定的数据字段定义 UI。有关更多信息,请参见如何:在数据模型中自定义数据字段显示。
如果使用的是 GridView 或 DetailsView 控件,则添加一个 DynamicField 对象并将其 UIHint 属性设置为字段模板名,用来显示数据。
下面的示例演示如何使用 DynamicField 控件通过一个名为 RedText 的字段模板,来呈现 ProductName 列。在显示模式中,通过使用一个名为 RedText.ascx 的字段模板来显示数据。在编辑或插入模式中,通过使用一个名为 RedText_Edit.ascx 的字段模板来显示数据。
<asp:DynamicField UIHint="RedText" DataField="ProductName" />
说明: 如果找不到指定的字段模板,则动态数据将使用回退机制。有关更多信息,请参见 ASP.NET 动态数据字段模板概述。
如果使用的是使用模板或模板字段的数据绑定控件,例如 ListView 或 FormView 控件,则添加一个 DynamicControl 控件用来显示数据,并将其 UIHint 属性设置为要显示的数据字段的名称。
下面的示例指定,当项目处于编辑模式时,将使用一个名为 RedText 的字段模板来呈现 ProductName 列。在运行时,动态数据将搜索名为 RedText_Edit.ascx 的用户控件。
<EditItemTemplate> <asp:DynamicControl runat="server" Mode="Edit" UIHint="RedText" DataField="ProductName" /> </EditItemTemplate>
示例
下面的示例演示如何将 UIHint 属性添加到 GridView 控件的 DynamicField 字段中。设置属性,以便数据字段使用自定义字段模板,该模板显示 Calendar 控件用于编辑中止日期。第二个和第三个示例演示字段模板的用户控件代码,用于定义 UI 以短格式显示日期并编辑字段。
<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
DynamicDataManager1.RegisterControl(ProductsGridView)
End Sub
</script>
<!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">
<head id="Head1" runat="server">
<title>UIHint Property Sample</title>
<link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<h2><%= ProductsDataSource.TableName%> table</h2>
<asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
AutoLoadForeignKeys="true" />
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"/>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="ProductsGridView" runat="server" DataSourceID="ProductsDataSource"
AutoGenerateEditButton="true"
AutoGenerateColumns="false"
AllowSorting="true"
AllowPaging="true">
<Columns>
<asp:DynamicField DataField="Name" />
<asp:DynamicField DataField="ProductNumber" />
<asp:DynamicField DataField="DiscontinuedDate" UIHint="DateCalendar" />
</Columns>
<EmptyDataTemplate>
There are currently no items in this table.
</EmptyDataTemplate>
</asp:GridView>
<!-- This example uses Microsoft SQL Server and connects -->
<!-- to the AdventureWorksLT sample database. -->
<asp:LinqDataSource ID="ProductsDataSource" runat="server"
EnableUpdate="true"
TableName="Products"
ContextTypeName="AdventureWorksLTDataContext" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Init(object sender, EventArgs e)
{
DynamicDataManager1.RegisterControl(ProductsGridView);
}
</script>
<!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">
<head id="Head1" runat="server">
<title>UIHint Property Sample</title>
<link href="~/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<h2><%= ProductsDataSource.TableName%> table</h2>
<asp:DynamicDataManager ID="DynamicDataManager1" runat="server"
AutoLoadForeignKeys="true" />
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"/>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="ProductsGridView" runat="server" DataSourceID="ProductsDataSource"
AutoGenerateEditButton="true"
AutoGenerateColumns="false"
AllowSorting="true"
AllowPaging="true">
<Columns>
<asp:DynamicField DataField="Name" />
<asp:DynamicField DataField="ProductNumber" />
<asp:DynamicField DataField="DiscontinuedDate" UIHint="DateCalendar" />
</Columns>
<EmptyDataTemplate>
There are currently no items in this table.
</EmptyDataTemplate>
</asp:GridView>
<asp:LinqDataSource ID="ProductsDataSource" runat="server"
EnableUpdate="true"
TableName="Products"
ContextTypeName="AdventureWorksLTDataContext" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
<%@ Control Language="VB" Inherits="System.Web.DynamicData.FieldTemplateUserControl" %>
<script runat="server">
Function GetDateString() As String
If Not (FieldValue Is Nothing) Then
Dim dt As DateTime = CType(FieldValue, DateTime)
Return dt.ToShortDateString()
Else
Return String.Empty
End If
End Function
</script>
<%# GetDateString() %>
<%@ Control Language="C#" Inherits="System.Web.DynamicData.FieldTemplateUserControl" %>
<script runat="server">
string GetDateString()
{
if (FieldValue != null)
{
DateTime dt = (DateTime)FieldValue;
return dt.ToShortDateString();
}
else
{
return string.Empty;
}
}
</script>
<%# GetDateString() %>
<%@ Control Language="VB" Inherits="System.Web.DynamicData.FieldTemplateUserControl" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
TextBox1.ToolTip = Column.Description
SetUpValidator(RequiredFieldValidator1)
SetUpValidator(RegularExpressionValidator1)
SetUpValidator(DynamicValidator1)
End Sub
Protected Overrides Sub ExtractValues(ByVal dictionary As IOrderedDictionary)
dictionary(Column.Name) = ConvertEditedValue(TextBox1.Text)
End Sub
Public Overrides ReadOnly Property DataControl() As Control
Get
Return TextBox1
End Get
End Property
Protected Sub Calendar1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs)
TextBox1.Text = Calendar1.SelectedDate.ToString("d")
End Sub
Function GetDateString() As String
If Not (FieldValue Is Nothing) Then
Dim dt As DateTime = CType(FieldValue, DateTime)
Return dt.ToShortDateString()
Else
Return String.Empty
End If
End Function
</script>
<asp:TextBox ID="TextBox1" runat="server"
Text='<%# GetDateString() %>'
MaxLength="10">
</asp:TextBox>
<asp:Calendar ID="Calendar1" runat="server"
VisibleDate='<%# IIf(FieldValue Is Nothing, DateTime.Now, FieldValue) %>'
SelectedDate='<%# IIf(FieldValue Is Nothing, DateTime.Now, FieldValue) %>'
OnSelectionChanged="Calendar1_SelectionChanged" />
<asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1"
CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
<asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1"
CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
<asp:DynamicValidator runat="server" ID="DynamicValidator1"
CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" />
<%@ Control Language="C#" Inherits="System.Web.DynamicData.FieldTemplateUserControl" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
TextBox1.ToolTip = Column.Description;
SetUpValidator(RequiredFieldValidator1);
SetUpValidator(RegularExpressionValidator1);
SetUpValidator(DynamicValidator1);
}
protected override void ExtractValues(IOrderedDictionary dictionary) {
dictionary[Column.Name] = ConvertEditedValue(TextBox1.Text);
}
public override Control DataControl
{
get
{
return TextBox1;
}
}
protected void Calendar1_SelectionChanged(object sender, EventArgs e)
{
TextBox1.Text = Calendar1.SelectedDate.ToString("d");
}
string GetDateString()
{
if (FieldValue != null)
{
DateTime dt = (DateTime)FieldValue;
return dt.ToShortDateString();
}
else
{
return string.Empty;
}
}
</script>
<asp:TextBox ID="TextBox1" runat="server"
Text='<%# GetDateString() %>'
MaxLength="10">
</asp:TextBox>
<asp:Calendar ID="Calendar1" runat="server"
VisibleDate='<%# (FieldValue != null) ? FieldValue : DateTime.Now %>'
SelectedDate='<%# (FieldValue != null) ? FieldValue : DateTime.Now %>'
OnSelectionChanged="Calendar1_SelectionChanged" />
<asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1"
CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
<asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1"
CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
<asp:DynamicValidator runat="server" ID="DynamicValidator1"
CssClass="droplist" ControlToValidate="TextBox1" Display="Dynamic" />
编译代码
此示例需要:
一个动态数据网站或动态数据 Web 应用程序。
AdventureWorks 或 AdventureWorksLT 示例数据库。有关如何下载和安装 SQL Server 示例数据库的信息,请参见 CodePlex 站点上的 Microsoft SQL Server Product Samples: Database(Microsoft SQL Server 产品示例:数据库)。请确保针对所运行的 SQL Server 版本(SQL Server 2005 或 SQL Server 2008)安装正确版本的示例数据库。
配置 LINQ to SQL 类来访问 AdventureWorks 或 AdventureWorksLT 数据库的 Products 表。
Global.asax 文件中的动态数据使用一个已注册的数据上下文对象。
可靠编程
以下情况可能会导致异常:
- 数据库不可用。