必须强调 3 点:
- 动态数据项目是基于 ASP.NET 构建的
- 动态数据依赖于一系列的模板,它们用于显示和编辑数据
- 动态数据应用中的一切都是可以进行自定义的
有很多方式可用来扩展、修改以及调整动态数据应用程序,因此,有时候对它们的选择会很困难。
使用模板进行自定义
模板是动态数据应用程序的核心。我将演示使用模板自定义数据被如何呈现到客户端的几个不同方式。其中一些技术要修改现有的模板,而另一些需要新模版,还有一些使用代码来扩展应用程序的行为。
所有这些方法都有助于强调 ASP.NET 动态数据系统的灵活性,而 ASP.NET 动态数据系统被设计为无痛苦的实现所有这些方法。
1. 编辑默认的模板
DynamicData\PageTemplates 目录包含显示、编辑、创建数据记录的默认模板,对它们的改变会影响到所有使用默认值的数据模型表。我们打开 List.aspx 默认模板并切换到设计视图,对 GridView 的基本行为略做改变(套用自动格式):
你会发现,这个改动影响了数据模型中所有表的列表视图,这正是你希望的,而其他视图(编辑、更新)保持不变,Default.aspx 页面也是如此。
2. 创建自定义模板
修改默认模板是很不错,但如果你只是希望自定义在处理的那个表怎么办?一个办法是创建一个自定义的页面模板并把它放到 DynamicData\CustomPages 目录。
假设 Products 表要使用不同的模板。在 CustomPages 目录下新建 Products 目录,并复制 List.aspx 页面进去(这么做最方便)。对这个 List.aspx 页面我做了如下的更改,取消了 GridView 的分页,设置了“红糖”的自动格式。现在运行程序会发现,除了 Products 列表应用了新的格式和没有分页,其余的表依然使用了默认模板。
创建这个自定义的模板就是这么简单,但必须遵循以下的规则:
- 目录名必须和应用新模版的表名完全相同
- 复制某种模板进新目录,然后进行修改即可(Edit、Details 模板如果你也复制过去进行修改的话)
3. 使用实体模板(所谓实体,指的就是单一记录)
实体模板是 ASP.NET 4 新增的。它不需要创建全新的模板就可以让你控制页面数据元素的布局。如果仔细观察默认的 Edit.aspx 以及 Details.aspx 模板,就会发现它们使用被称作 DynamicEntity 的控件。
切换到源代码视图,可以看到如下的语句:
<asp:DynamicEntity runat="server" Mode="Edit" />
DynamicEntity 控件为要显示的数据元素生成视图。它有 3 种模式:默认、编辑、新增,并和 DynamicData\EntityTemplates 目录中的 3 个文件相对应(Default.ascx、Default_Edit.ascx、Default_Insert.ascx)。
修改 3 个模板中的任意一个都会影响所有表数据元素的显示。我们来看看 Default.ascx 的代码:
<%@ Control Language="C#" CodeFile="Default.ascx.cs" Inherits="DefaultEntityTemplate" %>
<asp:EntityTemplate runat="server" ID="EntityTemplate1">
<ItemTemplate>
<tr class="td">
<td class="DDLightHeader">
<asp:Label runat="server" OnInit="Label_Init" />
</td>
<td>
<asp:DynamicControl runat="server" OnInit="DynamicControl_Init" />
</td>
</tr>
</ItemTemplate>
</asp:EntityTemplate>
在实体模板的页面中,每个字段都被显示为两栏。第一栏是字段的名称(数据库表的列名),第二栏显示值。Details.aspx 页面使用了 Default.ascx 元素模板,因此单击任意表行数据的 Details 链接后,就会看到下面相似的界面:
如果修改这个实体模板,就会影响所有使用它呈现的数据元素的外观,我们编辑一下这个模板以添加一些额外的结构:
<%@ Control Language="C#" CodeFile="Default.ascx.cs" Inherits="DefaultEntityTemplate" %>
<asp:EntityTemplate runat="server" ID="EntityTemplate1">
<ItemTemplate>
<tr class="td">
<td class="DDLightHeader">
<asp:Label runat="server" Text="Field name:" />
</td>
<td>
<asp:Label runat="server" OnInit="Label_Init" />
</td>
<td class="DDLightHeader">
<asp:Label runat="server" Text="Field value:" />
</td>
<td>
<asp:DynamicControl runat="server" OnInit="DynamicControl_Init" />
</td>
</tr>
</ItemTemplate>
</asp:EntityTemplate>
查看各个表的详细视图,你会发现这个修改在所有默认的范围中都生效了。修改通用模板时,必须小心保持 DynamicControl 的位置不变。这是因为这个模板将配合一系列的表来使用,你不会提前知道表结构会是什么样子。
如果只想为某个表修改数据元素的显示方式,就需要创建一个全新的实体模板。我们来为 Products 表创建一个自定义的实体模板。右击 EntityTemplates 目录,新增 Web 用户控件。实体模板的名称必须和要应用到的数据库表相匹配,此处应该是 Products.ascx。
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Products.ascx.cs"
Inherits="DynamicData_EntityTemplates_Products" %>
<tr class="td">
<td class="DDLightHeader">
<asp:Label ID="Label1" runat="server" Text="Product Name" />
</td>
<td>
<asp:DynamicControl ID="DynamicControl1" runat="server" DataField="ProductName" />
</td>
</tr>
<tr class="td">
<td class="DDLightHeader">
<asp:Label ID="Label2" runat="server" Text="Price per Unit" />
</td>
<td>
<asp:DynamicControl ID="DynamicControl2" runat="server" DataField="UnitPrice" />
</td>
</tr>
<tr class="td">
<td class="DDLightHeader">
<asp:Label ID="Label3" runat="server" Text="Discontinued?" />
</td>
<td>
<asp:DynamicControl ID="DynamicControl3" runat="server" DataField="Discontinued" />
</td>
</tr>
<tr class="td">
<td class="DDLightHeader">
<asp:Label ID="Label4" runat="server" Text="Units in Stock" />
</td>
<td>
<asp:DynamicControl ID="DynamicControl4" runat="server" DataField="UnitsInStock" />
</td>
</tr>
打开代码隐藏文件,引用命名空间 System.Web.DynamicData,把基类改为 EntityTemplateUserControl:
using System.Web.DynamicData;
public partial class DynamicData_EntityTemplates_Products : EntityTemplateUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
现在运行程序,Products 表中的 Details 已经使用了刚才新建的模板:
这里要强调的是,创建替换其他某个默认模板的自定义实体模板,必须遵循命名规范要求。如果要创建 Products 表的编辑实体模板,必须在 EntityTemplates 目录中创建名为 Products_Edit.aspx 的模板。
4. 自定义字段模板
如下图所示,这一组默认的字段模板,和实体模板控制行数据外观的方式一样,字段模板用来控制各个数据类型的外观。
动态数据系统根据数据模型的数据类型来判断字段显示时要使用的模板。理解它最好的办法是创建一个自定义模板。打开 Text_Edit.ascx 模板,进行一些修改,看下图:
我们增加了背景色和前景色的样式设置,现在运行程序,可以看见编辑模板中该类型的字段具有了新的颜色模式:
要修改其他类型的字段显示,如此操作即可。当然,Details 模板中的你只要修改不带后缀 _Edit 的那些字段模板即可。
这里要特别说明一点:不能通过创建新文件创建仅应用到特定表的特定类型的模板字段!例如,不能创建只应用到 Products 表的布尔类型的模板。不过,可以通过元数据来达到这一目的,这一点在后续文章中我会介绍。