配置文件、主题和 Web 部件

Microsoft

ASP.NET 2.0 中的配置和检测发生了重大更改。 新的 ASP.NET 配置 API 允许以编程方式进行配置更改。 此外,存在许多新的配置设置,允许新的配置和检测。

ASP.NET 2.0 表示个性化网站领域的显著改进。 除了我们已经介绍的成员资格功能外,ASP.NET 配置文件、主题和 Web 部件显著增强了网站的个性化。

ASP.NET 配置文件

ASP.NET 配置文件类似于会话。 区别在于,配置文件是永久性的,而会话在浏览器关闭时丢失。 会话和配置文件之间的另一大区别是配置文件是强类型,因此在开发过程中为你提供 IntelliSense。

配置文件在计算机配置文件或应用程序的 web.config 文件中定义。 (无法在 file.web.config子文件夹中定义配置文件。) 以下代码定义用于存储网站访问者名字和姓氏的配置文件。

<profile>
    <properties>
        <add name="FirstName" />
        <add name="LastName" />
    </properties>
</profile>

配置文件属性的默认数据类型为 System.String。 在上面的示例中,未指定数据类型。 因此,FirstName 和 LastName 属性都是 String 类型。 如前所述,配置文件属性是强类型的。 下面的代码为年龄添加了一个类型为 Int32 的新属性。

<profile>
    <properties>
        <add name="FirstName" />
        <add name="LastName" />
        <add name="Age" type="Int32"/>
    </properties>
</profile>

配置文件通常用于 ASP.NET Forms 身份验证。 与 Forms 身份验证结合使用时,每个用户都有一个单独的配置文件与其用户 ID 相关联。 但是,也可以使用配置文件中的 anonymousIdentification> 元素以及 allowAnonymous 属性在匿名应用程序中<使用配置文件,如下所示:

<anonymousIdentification enabled="true" />
<profile>
    <properties>
        <add name="FirstName" allowAnonymous="true" />
        <add name="LastName" allowAnonymous="true" />
    </properties>
</profile>

当匿名用户浏览站点时,ASP.NET 为该用户创建 ProfileCommon 实例。 此配置文件使用存储在浏览器上的 Cookie 中的唯一 ID 将用户标识为唯一访问者。 通过这种方式,你可以为匿名浏览的用户存储个人资料信息。

配置文件组

可以对配置文件的属性进行分组。 通过对属性进行分组,可以模拟特定应用程序的多个配置文件。

以下配置为两个组配置 FirstName 和 LastName 属性;买家和潜在客户。

<profile>
    <properties>
        <group name="Buyers">
            <add name="FirstName" />
            <add name="Lastname" />
            <add name="NumberOfPurchases" type="Int32" />
        </group>
        <group name="Prospects">
            <add name="FirstName" />
            <add name="Lastname" />
        </group>
    </properties>
</profile>

然后,可以设置特定组的属性,如下所示:

Profile.Buyers.NumberOfPurchases += 1;

存储复杂对象

到目前为止,我们介绍的示例已将简单数据类型存储在配置文件中。 还可以通过使用 serializeAs 属性指定序列化方法,在配置文件中存储复杂数据类型,如下所示:

<add name="PurchaseInvoice"
     type="PurchaseInvoice"
     serializeAs="Binary"
/>

在本例中,类型为 PurchaseInvoice。 PurchaseInvoice 类需要标记为可序列化,并且可以包含任意数量的属性。 例如,如果 PurchaseInvoice 有一个名为 NumItemsPurchased 的属性,则可以在代码中引用该属性,如下所示:

Profile.PurchaseInvoice.NumItemsPurchased

配置文件继承

可以创建用于多个应用程序的配置文件。 通过创建派生自 ProfileBase 的配置文件类,可以使用 inherits 属性在多个应用程序中重用配置文件,如下所示:

<profile inherits="PurchasingProfile" />

在本例中, 类 PurchasingProfile 如下所示:

using System;
using System.Web.Profile;
public class PurchasingProfile : ProfileBase {
    private string _ProductName;
    private Int32 _ProductID;
    public string ProductName {
        get { return _ProductName; }
        set { _ProductName = value; }
    }
    public Int32 ProductID {
        get { return _ProductID; }
        set { _ProductID = value; }
    }
}

配置文件提供程序

ASP.NET 配置文件使用提供程序模型。 默认提供程序使用 SqlProfileProvider 提供程序将信息存储在 Web 应用程序的 App_Data 文件夹中的 SQL Server Express 数据库中。 如果数据库不存在,ASP.NET 会在配置文件尝试存储信息时自动创建它。

但在某些情况下,你可能想要开发自己的配置文件提供程序。 ASP.NET 配置文件功能使你能够轻松使用不同的提供程序。

在出现错误时,可以创建自定义配置文件提供程序:

  • 需要在数据源(例如 FoxPro 数据库或 Oracle 数据库)中存储配置文件信息,而.NET Framework随附的配置文件提供程序不支持这一点。
  • 需要使用数据库架构来管理配置文件信息,该数据库架构不同于.NET Framework中包含的提供程序所使用的数据库架构。 一个常见示例是,你想要将配置文件信息与现有 SQL Server 数据库中的用户数据集成。

所需类

若要实现配置文件提供程序,请创建一个继承 System.Web.Profile.ProfileProvider 抽象类的类。 ProfileProvider 抽象类反过来继承 System.Configuration.SettingsProvider 抽象类,后者继承 System.Configuration.Provider.ProviderBase 抽象类。 由于此继承链,除了 ProfileProvider 类的必需成员外,还必须实现 SettingsProviderProviderBase 类的必需成员。

下表描述了必须从 ProviderBaseSettingsProviderProfileProvider 抽象类实现的属性和方法。

ProviderBase 成员

成员 说明
Initialize 方法 采用提供程序实例的名称和配置设置的 NameValueCollection 作为输入。 用于设置提供程序实例的选项和属性值,包括在计算机配置或Web.config文件中指定的特定于实现的值和选项。

SettingsProvider 成员

成员 说明
ApplicationName 属性 与每个配置文件一起存储的应用程序名称。 配置文件提供程序使用应用程序名称来单独存储每个应用程序的配置文件信息。 这样,如果在不同的应用程序中创建了同一用户名,则多个 ASP.NET 应用程序可以使用同一数据源,而不会发生冲突。 或者,多个 ASP.NET 应用程序可以通过指定相同的应用程序名称来共享配置文件数据源。
GetPropertyValues 方法 将 SettingsContext 和 SettingsPropertyCollection 对象作为输入。 SettingsContext 提供有关用户的信息。 可以使用这些信息作为主键来检索用户的配置文件属性信息。 使用 SettingsContext 对象获取用户名以及用户是经过身份验证还是匿名。 SettingsPropertyCollection 包含 SettingsProperty 对象的集合。 每个 SettingsProperty 对象提供属性的名称和类型以及其他信息,例如属性的默认值以及属性是否为只读。 GetPropertyValues 方法根据作为输入提供的 SettingsProperty 对象,使用 SettingsPropertyValue 对象填充 SettingsPropertyValueCollection。 指定用户的数据源中的值将分配给每个 SettingsPropertyValue 对象的 PropertyValue 属性,并返回整个集合。 调用 方法还会将指定用户配置文件的 LastActivityDate 值更新为当前日期和时间。
SetPropertyValues 方法 SettingsContextSettingsPropertyValueCollection 对象作为输入。 SettingsContext 提供有关用户的信息。 可以使用这些信息作为主键来检索用户的配置文件属性信息。 使用 SettingsContext 对象获取用户名以及用户是经过身份验证还是匿名。 SettingsPropertyValueCollection 包含 SettingsPropertyValue 对象的集合。 每个 SettingsPropertyValue 对象都提供属性的名称、类型和值以及其他信息,例如属性的默认值以及属性是否为只读。 SetPropertyValues 方法更新指定用户的数据源中的配置文件属性值。 调用 方法还会将指定用户配置文件的 LastActivityDate 和 LastUpdatedDate 值更新为当前日期和时间。

ProfileProvider 成员

成员 说明
DeleteProfiles 方法 采用用户名的字符串数组作为输入,并从数据源中删除应用程序名称与 ApplicationName 属性值匹配的指定名称的所有配置文件信息和属性值。 如果数据源支持事务,则建议在事务中包含所有删除操作,并回滚该事务,并在任何删除操作失败时引发异常。
DeleteProfiles 方法 将 ProfileInfo 对象的集合作为输入,并从数据源中删除应用程序名称与 ApplicationName 属性值匹配的每个配置文件的所有配置文件信息和属性值。 如果数据源支持事务,建议在事务中包含所有删除操作并回滚事务,并在任何删除操作失败时引发异常。
DeleteInactiveProfiles 方法 将 ProfileAuthenticationOption 值和 DateTime 对象作为输入,并从数据源中删除上次活动日期小于或等于指定日期和时间且应用程序名称与 ApplicationName 属性值匹配的所有配置文件信息和属性值。 ProfileAuthenticationOption 参数指定是仅删除匿名配置文件、仅经过身份验证的配置文件还是所有配置文件。 如果数据源支持事务,建议在事务中包含所有删除操作,并回滚该事务,并在任何删除操作失败时引发异常。
GetAllProfiles 方法 ProfileAuthenticationOption 值、指定页索引的整数、指定页面大小的整数和对将设置为配置文件总数的整数的引用作为输入。 返回一个 ProfileInfoCollection,其中包含数据源中应用程序名称与 ApplicationName 属性值匹配的所有配置文件的 ProfileInfo 对象。 ProfileAuthenticationOption 参数指定是仅返回匿名配置文件、仅经过身份验证的配置文件还是返回所有配置文件。 GetAllProfiles 方法返回的结果受页面索引和页面大小值的约束。 页面大小值指定要在 ProfileInfoCollection 中返回的最大 ProfileInfo 对象数。 页面索引值指定要返回的结果页,其中 1 标识第一页。 记录总数的参数是一个 out 参数, (可以在 Visual Basic) 中使用 ByRef ,该参数设置为配置文件总数。 例如,如果数据存储包含应用程序的 13 个配置文件,并且页面索引值为 2,页面大小为 5,则返回的 ProfileInfoCollection 包含第六个到第十个配置文件。 方法返回时,记录总数值设置为 13。
GetAllInactiveProfiles 方法 ProfileAuthenticationOption 值、 DateTime 对象、指定页索引的整数、指定页面大小的整数和对将设置为配置文件总数的整数的引用作为输入。 返回一个 ProfileInfoCollection,其中包含数据源中最后一个活动日期小于或等于指定 DateTime 且应用程序名称与 ApplicationName 属性值匹配的所有配置文件的 ProfileInfo 对象。 ProfileAuthenticationOption 参数指定是仅返回匿名配置文件、仅经过身份验证的配置文件还是返回所有配置文件。 GetAllInactiveProfiles 方法返回的结果受页面索引和页面大小值的约束。 页面大小值指定要在 ProfileInfoCollection 中返回的最大 ProfileInfo 对象数。 页面索引值指定要返回的结果页,其中 1 标识第一页。 记录总数的参数是一个 out 参数, (可以在 Visual Basic) 中使用 ByRef ,该参数设置为配置文件总数。 例如,如果数据存储包含应用程序的 13 个配置文件,并且页面索引值为 2,页面大小为 5,则返回的 ProfileInfoCollection 包含第六个到第十个配置文件。 方法返回时,记录总数值设置为 13。
FindProfilesByUserName 方法 ProfileAuthenticationOption 值、包含用户名的字符串、指定页面索引的整数、指定页面大小的整数和对将设置为配置文件总数的整数的引用作为输入。 返回一个 ProfileInfoCollection ,其中包含数据源中所有配置文件的 ProfileInfo 对象,其中用户名与指定用户名匹配,应用程序名称与 ApplicationName 属性值匹配。 ProfileAuthenticationOption 参数指定是仅返回匿名配置文件、仅经过身份验证的配置文件还是返回所有配置文件。 如果数据源支持其他搜索功能(如通配符),则可以为用户名提供更广泛的搜索功能。 FindProfilesByUserName 方法返回的结果受页面索引和页面大小值的约束。 页面大小值指定要在 ProfileInfoCollection 中返回的最大 ProfileInfo 对象数。 页面索引值指定要返回的结果页,其中 1 标识第一页。 记录总数的参数是一个 out 参数, (可以在 Visual Basic) 中使用 ByRef ,该参数设置为配置文件总数。 例如,如果数据存储包含应用程序的 13 个配置文件,并且页面索引值为 2,页面大小为 5,则返回的 ProfileInfoCollection 包含第六个到第十个配置文件。 方法返回时,记录总数值设置为 13。
FindInactiveProfilesByUserName 方法 ProfileAuthenticationOption 值、包含用户名的字符串、 DateTime 对象、指定页面索引的整数、指定页面大小的整数和对将设置为配置文件总数的整数的引用作为输入。 返回一个 ProfileInfoCollection ,其中包含数据源中所有配置文件的 ProfileInfo 对象,其中用户名与指定用户名匹配,其中最后一个活动日期小于或等于指定的 DateTime,应用程序名称与 ApplicationName 属性值匹配。 ProfileAuthenticationOption 参数指定是仅返回匿名配置文件、仅经过身份验证的配置文件还是返回所有配置文件。 如果数据源支持其他搜索功能(如通配符),则可以为用户名提供更广泛的搜索功能。 FindInactiveProfilesByUserName 方法返回的结果受页面索引和页面大小值的约束。 页面大小值指定要在 ProfileInfoCollection 中返回的最大 ProfileInfo 对象数。 页面索引值指定要返回的结果页,其中 1 标识第一页。 记录总数的参数是一个 out 参数, (可以在 Visual Basic) 中使用 ByRef ,该参数设置为配置文件总数。 例如,如果数据存储包含应用程序的 13 个配置文件,并且页面索引值为 2,页面大小为 5,则返回的 ProfileInfoCollection 包含第六个到第十个配置文件。 方法返回时,记录总数值设置为 13。
GetNumberOfInActiveProfiles 方法 ProfileAuthenticationOption 值和 DateTime 对象作为输入,并返回数据源中最后一个活动日期小于或等于指定 DateTime 且应用程序名称与 ApplicationName 属性值匹配的所有配置文件的计数。 ProfileAuthenticationOption 参数指定是仅对匿名配置文件、仅经过身份验证的配置文件还是所有配置文件进行计数。

ApplicationName

由于配置文件提供程序为每个应用程序单独存储配置文件信息,因此必须确保数据架构包含应用程序名称,并且查询和更新还包括应用程序名称。 例如,以下命令用于根据用户名以及配置文件是否匿名从数据库中检索属性值,并确保 ApplicationName 值包含在查询中。

SELECT Property
FROM PropertyTable
WHERE Username = 'user1'
AND IsAnonymous = False
AND ApplicationName = 'MyApplication'

ASP.NET 主题

什么是 ASP.NET 2.0 主题?

Web 应用程序最重要的方面之一是整个网站的外观一致。 ASP.NET 1.x 开发人员通常使用级联样式表 (CSS) 来实现一致的外观。 ASP.NET 2.0 主题显著改进了 CSS,因为它们使 ASP.NET 开发人员能够定义 ASP.NET 服务器控件以及 HTML 元素的外观。 ASP.NET 主题可以应用于单个控件、特定网页或整个 Web 应用程序。 主题使用 CSS 文件、可选外观文件和可选图像目录(如果需要图像)的组合。 外观文件控制 ASP.NET 服务器控件的视觉外观。

主题存储在哪里?

主题的存储位置根据其范围而异。 可应用于任何应用程序的主题存储在以下文件夹中:

C:\WINDOWS\Microsoft.NET\Framework\v2.x.xxxxx\ASP.NETClientFiles\Themes\<Theme_Name>

特定于特定应用程序的主题存储在网站根目录的目录中 App\_Themes\<Theme\_Name>

注意

外观文件应仅修改影响外观的服务器控件属性。

全局主题是一个主题,可应用于 Web 服务器上运行的任何应用程序或网站。 默认情况下,这些主题存储在 ASP 中。v2.x.xxxxx 目录内的 NETClientfiles\Themes 目录。 或者,可以将主题文件移动到网站根目录的 aspnet_client/system_web/[version]/Themes/[theme_name] 文件夹中。

特定于应用程序的主题只能应用于文件所在的应用程序。 这些文件存储在 App\_Themes/<theme\_name> 网站的根目录下。

主题的组件

主题由一个或多个 CSS 文件、可选外观文件和可选 Images 文件夹组成。 CSS 文件可以是你想要的任何名称 (即 default.css 或 theme.css 等) ,并且必须位于主题文件夹的根目录中。 CSS 文件用于定义特定选择器的普通 CSS 类和属性。 若要将其中一个 CSS 类应用于页面元素,请使用 CSSClass 属性。

外观文件是一个 XML 文件,其中包含 ASP.NET 服务器控件的属性定义。 下面列出的代码是一个示例外观文件。

<asp:TextBox runat="server"
    BackColor="#FFC080"
    BorderColor="Black"
    BorderStyle="Solid"
    BorderWidth="1px"
    Font-Names="Tahoma, Verdana, Arial"
    Font-Size="Smaller" />

<asp:Button runat="server"
    BackColor="#C04000"
    BorderColor="Maroon"
    BorderStyle="Solid"
    BorderWidth="2px"
    Font-Names="Tahoma,Verdana,Arial"
    Font-Size="Smaller"
    ForeColor="#FFFFC0" />

下面的图 1 显示了浏览的小型 ASP.NET 页面,但未应用主题。 图 2 显示了应用了主题的同一文件。 背景色和文本颜色通过 CSS 文件进行配置。 按钮和文本框的外观是使用上面列出的外观文件配置的。

无主题

图 1:无主题

应用的主题

图 2:应用的主题

上面列出的外观文件为所有 TextBox 控件和 Button 控件定义默认外观。 这意味着插入到页面上的每个 TextBox 控件和按钮控件都将呈现此外观。 还可以使用控件的 SkinID 属性定义可应用于这些控件的特定实例的外观。

下面的代码为 Button 控件定义外观。 只有具有 GoButton的 SkinID 属性的 Button 控件才会显示外观。

<asp:Button runat="server"
    BackColor="#C04000"
    BorderColor="Maroon"
    BorderStyle="Solid"
    BorderWidth="2px"
    Font-Names="Tahoma,Verdana,Arial"
    Font-Size="Smaller"
    ForeColor="#FFFFC0"
    Text=go
    SkinID=goButton
    Width="95px" />

每个服务器控件类型只能有一个默认外观。 如果需要其他外观,则应使用 SkinID 属性。

将主题应用于页面

可以使用以下任一方法应用主题:

  • <在 web.config 文件的 pages> 元素中
  • @Page在页面的 指令中
  • 以编程方式

在配置文件中应用主题

若要在应用程序配置文件中应用主题,请使用以下语法:

<system.web>
    <pages theme="CoolTheme" />
    ...
</system.web>

此处指定的主题名称必须与主题文件夹的名称匹配。 此文件夹可以存在于本课程前面提到的任意一个位置中。 如果尝试应用不存在的主题,将发生配置错误。

在 Page 指令中应用主题

还可以在 @ Page 指令中应用主题。 此方法允许对特定页面使用主题。

若要在 指令中 @Page 应用主题,请使用以下语法:

<%@ Page Language="C#" Theme=CoolTheme CodeFile="Default.aspx.cs" ... %>

同样,此处指定的主题必须与前面提到的主题文件夹匹配。 如果尝试应用不存在的主题,将发生生成失败。 Visual Studio 还会突出显示 属性,并通知你不存在此类主题。

以编程方式应用主题

若要以编程方式应用主题,必须在 Page_PreInit 方法中为页面指定 Theme 属性。

若要以编程方式应用主题,请使用以下语法:

Page.Theme = CoolTheme;

由于页面生命周期的原因,有必要在 PreInit 方法中应用主题。 如果在此时间点之后应用它,则运行时已应用页面主题,并且此时的更改在生命周期中已过晚。 如果应用不存在的主题,则会发生 HttpException 。 以编程方式应用主题时,如果任何服务器控件都指定了 SkinID 属性,则会发生生成警告。 此警告旨在通知你未以声明方式应用任何主题,并且可以忽略该主题。

练习 1:应用主题

在本练习中,你将对网站应用 ASP.NET 主题。

重要

如果使用 Microsoft Word在外观文件中输入信息,请确保不要将常规引号替换为智能引号。 智能引号会导致外观文件出现问题。

  1. 创建新的 ASP.NET 网站。

  2. 右键单击解决方案资源管理器中的项目,然后选择“添加新项”。

  3. 从文件列表中选择“Web 配置文件”,然后单击“添加”。

  4. 右键单击解决方案资源管理器中的项目,然后选择“添加新项”。

  5. 选择“外观文件”,然后单击“添加”。

  6. 当系统询问是否要将文件放在App_Themes文件夹中时,单击“是”。

  7. 在 解决方案资源管理器 中右键单击 App_Themes 文件夹中的 SkinFile 文件夹,然后选择“添加新项”。

  8. 从文件列表中选择“样式表”,然后单击“添加”。 现在,你已拥有实现新主题所需的所有文件。 但是,Visual Studio 已将主题文件夹命名为 SkinFile。 右键单击该文件夹,并将名称更改为 CoolTheme。

  9. 打开 SkinFile.skin 文件并在文件末尾添加以下代码:

    <asp:TextBox runat="server"
        BackColor="#FFC080"
        BorderColor="Black"
        BorderStyle="Solid"
        BorderWidth="1px"
        Font-Names="Tahoma, Verdana, Arial"
        Font-Size="Smaller"
    />
    
    <asp:Button runat="server"
        BackColor="#C04000"
        BorderColor="Maroon"
        BorderStyle="Solid"
        BorderWidth="2px"
        Font-Names="Tahoma,Verdana,Arial"
        Font-Size="Smaller"
        ForeColor="#FFFFC0"
    />
    
    <asp:Button runat="server"
        BackColor="#C04000"
        BorderColor="Maroon"
        BorderStyle="Solid"
        BorderWidth="2px"
        Font-Names="Tahoma,Verdana,Arial"
        Font-Size="Smaller"
        ForeColor="#FFFFC0"
        Text="go"
        SkinID="goButton"
        Width="95px"
    />
    
  10. 保存 SkinFile.skin 文件。

  11. 打开 StyleSheet.css。

  12. 将其中的所有文本替换为以下内容:

    body {
        background-color: #FFDEAD;
    }
    
  13. 保存 StyleSheet.css 文件。

  14. 打开 Default.aspx 页。

  15. 添加 TextBox 控件和 Button 控件。

  16. 保存页。 现在浏览 Default.aspx 页。 它应显示为普通 Web 窗体。

  17. 打开 Web.config 文件。

  18. 直接在开始 <system.web> 标记下方添加以下内容:

    <pages theme="CoolTheme" />
    
  19. 保存 web.config 文件。 现在浏览 Default.aspx 页。 它应显示并应用了主题。

  20. 如果尚未打开,请在 Visual Studio 中打开 Default.aspx 页。

  21. 选择“按钮”。

  22. SkinID 属性更改为 goButton。 请注意,Visual Studio 提供了一个下拉列表,其中包含 Button 控件的有效 SkinID 值。

  23. 保存页。 现在再次在浏览器中预览页面。 按钮现在应显示“go”,并且外观应更宽。

使用 SkinID 属性,可以轻松地为特定类型的服务器控件的不同实例配置不同的外观。

StyleSheetTheme 属性

到目前为止,我们只讨论如何使用 Theme 属性应用主题。 使用 Theme 属性时,外观文件将替代服务器控件的任何声明性设置。 例如,在练习 1 中,你为 Button 控件指定了“goButton”的 SkinID,并将按钮的文本更改为“go”。 你可能已注意到,设计器中 Button 的 Text 属性已设置为“Button”,但主题会覆盖该属性。 主题将始终替代设计器中的任何属性设置。

如果希望能够使用设计器中指定的属性替代主题外观文件中定义的属性,可以使用 StyleSheetTheme 属性而不是 Theme 属性。 StyleSheetTheme 属性与 Theme 属性相同,只不过它不会像 Theme 属性那样重写所有显式属性设置。

若要了解此操作的操作,请从练习 1 中的项目打开web.config文件,并将 <pages> 元素更改为以下内容:

<pages styleSheetTheme="CoolTheme" />

现在浏览 Default.aspx 页,你将看到 Button 控件再次具有“Button”的 Text 属性。 这是因为设计器中的显式属性设置正在覆盖由 goButton SkinID 设置的 Text 属性。

重写主题

通过在应用程序的 App_Themes 文件夹中应用同名的主题,可以覆盖全局主题。 但是,主题不会在真正的重写方案中应用。 如果运行时在 App_Themes 文件夹中遇到主题文件,它将使用这些文件应用主题,并将忽略全局主题。

StyleSheetTheme 属性是可重写的,可以在代码中重写,如下所示:

const String THEME_NAME = "CoolTheme";
public override string StyleSheetTheme {
    get { return THEME_NAME; }
    set { Page.StyleSheetTheme = THEME_NAME; }
}

Web 部件

ASP.NET Web 部件是一组集成的控件,用于创建网站,使最终用户能够直接从浏览器修改网页的内容、外观和行为。 修改可以应用于网站上的所有用户或单个用户。 当用户修改页面和控件时,可以保存设置以在将来的浏览器会话中保留用户的个人首选项,这是一项称为个性化功能。 这些 Web 部件功能意味着开发人员可以让最终用户动态个性化 Web 应用程序,而无需开发人员或管理员干预。

使用 Web 部件控件集,作为开发人员,你可以使最终用户能够:

  • 个性化页面内容。 用户可以向页面添加新的 Web 部件控件、将其删除、隐藏或像普通窗口一样最小化。
  • 个性化页面布局。 用户可以将 Web 部件控件拖动到页面上的其他区域,或更改其外观、属性和行为。
  • 导出和导入控件。 用户可以导入或导出 Web 部件控件设置以用于其他页面或网站,从而保留控件中的属性、外观甚至数据。 这减少了最终用户的数据输入和配置需求。
  • 创建连接。 用户可以在控件之间建立连接,以便图表控件可以在股票股票代码控件中显示数据的图形。 用户不仅可以个性化连接本身,还可以个性化图表控件显示数据的方式的外观和详细信息。
  • 管理和个性化网站级别设置。 授权用户可以配置站点级设置、确定谁可以访问网站或页面、设置对控件的基于角色的访问等。 例如,具有管理角色的用户可以将 Web 部件控件设置为由所有用户共享,并阻止非管理员用户个性化共享控件。

通常,你将通过以下三种方式之一使用 Web 部件:创建使用 Web 部件控件的页面、创建单个 Web 部件控件,或创建完整的可个性化 Web 应用程序,例如门户。

页面开发

页面开发人员可以使用可视设计工具(如 Microsoft Visual Studio 2005)创建使用 Web 部件的页面。 使用 Visual Studio 等工具的一个优点是 Web 部件控件集提供在可视化设计器中拖放创建和配置 Web 部件控件的功能。 例如,可以使用设计器将 Web 部件区域或 Web 部件编辑器控件拖到设计图面上,然后使用 Web 部件控件集提供的 UI 在设计器中直接配置控件。 这可以加快 Web 部件应用程序的开发速度,并减少必须编写的代码量。

控件开发

可以将任何现有 ASP.NET 控件用作 Web 部件控件,包括标准 Web 服务器控件、自定义服务器控件和用户控件。 对于环境的最大编程控制,还可以创建派生自 WebPart 类的自定义 Web 部件控件。 对于单个 Web 部件控件开发,通常会创建用户控件并将其用作 Web 部件控件,或开发自定义 Web 部件控件。

作为开发自定义 Web 部件控件的示例,您可以创建一个控件来提供其他 ASP.NET 服务器控件提供的任何功能,这些功能可用于打包为可个性化 Web 部件控件:日历、列表、财务信息、新闻、计算器、用于更新内容的 RTF 控件、连接到数据库的可编辑网格、 动态更新其显示或天气和旅行信息的图表。 如果向可视化设计器提供控件,则任何使用 Visual Studio 的页面开发人员只需将控件拖动到 Web 部件区域并在设计时对其进行配置,而无需编写其他代码。

个性化是 Web 部件功能的基础。 它使用户能够修改或个性化页面上 Web 部件控件的布局、外观和行为。 个性化设置是长期存在的:它们不仅在当前浏览器会话期间保留 (与视图状态) 一样,还会在长期存储中保留,以便用户设置也保存以供将来的浏览器会话使用。 默认情况下,为 Web 部件页启用个性化设置。

UI 结构组件依赖于个性化,并提供所有 Web 部件控件所需的核心结构和服务。 每个 Web 部件页上所需的一个 UI 结构组件是 WebPartManager 控件。 尽管从不可见,但此控件具有协调页面上所有 Web 部件控件的关键任务。 例如,它跟踪所有单独的 Web 部件控件。 它管理 Web 部件区域 (页面上包含 Web 部件控件的区域) ,以及哪些控件位于哪些区域中。 它还跟踪和控制页面可以采用的不同显示模式,例如浏览、连接、编辑或目录模式,以及个性化更改是应用于所有用户还是应用于单个用户。 最后,它启动并跟踪 Web 部件控件之间的连接和通信。

第二种 UI 结构组件是区域。 区域充当 Web 部件页上的布局管理器。 它们包含和组织派生自 Part 类的控件 (部件控件) ,并提供在水平方向或垂直方向进行模块化页面布局的功能。 区域还提供常见且一致的 UI 元素 (,例如页眉和页脚样式、标题、边框样式、操作按钮等,它们包含的每个控件) ;这些常见元素称为控件的部件版式。 多种专用区域类型用于不同的显示模式和各种控件。 以下 Web 部件基本控件部分介绍了不同类型的区域。

所有派生自 Part 类的 Web 部件 UI 控件构成 Web 部件页上的主要 UI。 Web 部件控件集在提供用于创建部件控件的选项中具有灵活性和包容性。 除了创建自己的自定义 Web 部件控件外,还可以将现有的 ASP.NET 服务器控件、用户控件或自定义服务器控件用作 Web 部件控件。 下一节将介绍最常用于创建 Web 部件页的基本控件。

Web 部件基本控件

Web 部件控件集很广泛,但某些控件是必需的,因为它们是 Web 部件正常工作所必需的,或者因为它们是 Web 部件页面上最常用的控件。 当您开始使用 Web 部件并创建基本 Web 部件页时,熟悉下表中所述的基本 Web 部件控件会很有帮助。

Web 部件控件 说明
WebPartManager 管理页面上的所有 Web 部件控件。 每个 Web 部件页只需要一个 (和一个) WebPartManager 控件。
CatalogZone 包含 CatalogPart 控件。 使用此区域创建 Web 部件控件的目录,用户可以从中选择要添加到页面的控件。
EditorZone 包含 EditorPart 控件。 使用此区域,用户可以编辑和个性化页面上的 Web 部件控件。
WebPartZone 包含并提供 WebPart 控件的整体布局,这些控件构成页面的main UI。 每当使用 Web 部件控件创建页面时,都使用此区域。 页面可以包含一个或多个区域。
ConnectionsZone 包含 WebPartConnection 控件,并提供用于管理连接的 UI。
WebPart (GenericWebPart) 呈现主 UI;大多数 Web 部件 UI 控件属于此类别。 对于最大编程控件,可以创建派生自基本 WebPart 控件的自定义 Web 部件 控件。 还可以将现有服务器控件、用户控件或自定义控件用作 Web 部件控件。 每当这些控件中的任何一个放置在区域中时, WebPartManager 控件都会在运行时使用 GenericWebPart 控件自动包装它们,以便你可以将它们与 Web 部件功能一起使用。
CatalogPart 包含用户可添加到页面的可用 Web 部件控件的列表。
WebPartConnection 在页面上的两个 Web 部件控件之间创建连接。 连接将其中一个 Web 部件控件定义为数据) 的提供程序 (,将另一个定义为使用者。
EditorPart 用作专用编辑器控件的基类。
EditorPart 控件 (AppearanceEditorPart、LayoutEditorPart、BehaviorEditorPart 和 PropertyGridEditorPart) 允许用户对页面上 Web 部件 UI 控件的各个方面进行个性化设置

实验室:创建 Web 部件页

在本实验室中,你将创建一个 Web 部件页,用于通过 ASP.NET 配置文件保存信息。

使用 Web 部件创建简单页面

在本演练的此部分中,将创建一个使用 Web 部件控件显示静态内容的页面。 使用 Web 部件的第一步是创建具有两个必需结构元素的页面。 首先,Web 部件页需要 WebPartManager 控件来跟踪和协调所有 Web 部件控件。 其次,Web 部件页需要一个或多个区域,这些区域是包含 WebPart 或其他服务器控件并占用页面的指定区域的复合控件。

注意

无需执行任何操作即可启用 Web 部件个性化;默认情况下,它为 Web 部件控件集启用。 首次在网站上运行 Web 部件页时,ASP.NET 设置默认个性化设置提供程序来存储用户个性化设置。 有关个性化设置的详细信息,请参阅 Web 部件个性化概述。

创建包含 Web 部件控件的页面

  1. 关闭默认页面,并将新页面添加到名为 WebPartsDemo.aspx 的网站。

  2. 切换到 “设计” 视图。

  3. 在“ 视图 ”菜单中,确保选中 “非可视控件 ”和 “详细信息” 选项,以便可以查看没有 UI 的布局标记和控件。

  4. 将插入点放在设计图面上的标记之前 <div> ,然后按 Enter 添加新线条。 将插入点置于新行字符之前,单击菜单上的“ 块格式” 下拉列表控件,然后选择“ 标题 1 ”选项。 在标题中,添加文本 “Web 部件演示页”。

  5. 在“工具箱”的“ WebParts ”选项卡中,将 WebPartManager 控件拖到绘图页上,使其紧跟在新行字符之后和标记之前 <div>

    WebPartManager 控件不呈现任何输出,因此它在设计器图面上显示为灰色框。

  6. 将插入点置于标记内 <div>

  7. “布局 ”菜单中,单击“ 插入表格”,然后创建一个包含一行三列的新表。 单击“单元格属性”按钮,从“垂直对齐”下拉列表中选择顶部,单击“确定”,然后再次单击“确定”以创建表。

  8. 将 WebPartZone 控件拖到左侧表格列中。 右键单击 WebPartZone 控件,选择 “属性”,然后设置以下属性:

    ID:SidebarZone

    HeaderText:边栏

  9. 将第二个 WebPartZone 控件拖动到中间表列中并设置以下属性:

    ID:MainZone

    HeaderText:Main

  10. 保存文件。

页面现在有两个不同的区域,你可以单独控制这些区域。 但是,两个区域都没有任何内容,因此创建内容是下一步。 在本演练中,你将使用仅显示静态内容的 Web 部件控件。

Web 部件区域的布局由 <zonetemplate> 元素指定。 在区域模板中,可以添加任何 ASP.NET 控件,无论是自定义 Web 部件控件、用户控件还是现有服务器控件。 请注意,此处使用的是 Label 控件,而你只是添加静态文本。 在 WebPartZone 区域中放置常规服务器控件时,ASP.NET 在运行时将控件视为 Web 部件控件,从而在控件上启用 Web 部件功能。

为main区域创建内容

  1. “设计” 视图中,将 “标签” 控件从“工具箱”的“ 标准 ”选项卡拖动到 ID 属性设置为 MainZone 的区域的内容区域。

  2. 切换到 “源” 视图。 请注意,添加了一个 <zonetemplate> 元素来包装 MainZone 中的 Label 控件。

  3. 将名为 title 的属性添加到 <asp:label> 元素,并将其值设置为 Content。 从 <asp:label 元素中删除 Text=“Label> ”属性。 在 asp:label> 元素的<开始和结束标记之间,在一对 <h2> 元素标记中添加一些文本,例如“欢迎使用我的主页”。 代码应如下所示。

    <asp:webpartzone id="MainZone" runat="server" headertext="Main">
        <zonetemplate>
            <asp:label id="Label1" runat="server" title="Content">
                <h2>Welcome to My Home Page</h2>
            </asp:label>
        </zonetemplate>
    </asp:webpartzone>
    
  4. 保存文件。

接下来,创建一个用户控件,该控件也可以作为 Web 部件控件添加到页面。

创建用户控件

  1. 向网站添加新的 Web 用户控件,用作搜索控件。 取消选择将 源代码放在单独文件中的选项。 将其添加到 WebPartsDemo.aspx 页面所在的目录中,并将其命名为 SearchUserControl.ascx。

    注意

    本演练的用户控件不实现实际的搜索功能;它仅用于演示 Web 部件功能。

  2. 切换到 “设计” 视图。 从“工具箱”的“ 标准 ”选项卡中,将 TextBox 控件拖到页面上。

  3. 将插入点放在刚刚添加的文本框之后,然后按 Enter 添加新行。

  4. 将 Button 控件拖到刚刚添加的文本框下方新行上的页面上。

  5. 切换到 “源” 视图。 确保用户控件的源代码如以下示例所示。

    <%@ control language="C#"
        classname="SearchUserControl" %>
    <asp:textbox runat="server"
      id=" TextBox1"></asp:textbox>
    <br />
    <asp:button runat="server"
      id=" Button1" text="Search" />
    
  6. 保存并关闭该文件。

现在,可以将 Web 部件控件添加到边栏区域。 你要向边栏区域添加两个控件,一个包含链接列表,另一个是你在上一过程中创建的用户控件。 链接添加为标准 标签 服务器控件,类似于为 Main 区域创建静态文本的方式。 但是,尽管用户控件中包含的单个服务器控件可以直接包含在区域 (与标签控件) 一样,但在这种情况下,它们不是。 相反,它们是在上一过程中创建的用户控件的一部分。 这演示了一种在用户控件中打包所需控件和额外功能的常用方法,然后将区域中的该控件引用为 Web 部件控件。

在运行时,Web 部件控件集使用 GenericWebPart 控件包装这两个控件。 当 GenericWebPart 控件包装 Web 服务器控件时,泛型部件控件是父控件,你可以通过父控件的 ChildControl 属性访问服务器控件。 这种泛型部件控件的使用使标准 Web 服务器控件具有与派生自 WebPart 类的 Web 部件控件相同的基本行为和属性。

将 Web 部件控件添加到边栏区域

  1. 打开 WebPartsDemo.aspx 页。

  2. 切换到 “设计” 视图。

  3. 将创建的用户控件页 SearchUserControl.ascx 从 解决方案资源管理器 拖到 ID 属性设置为 SidebarZone 的区域,然后将其放在该区域中。

  4. 保存 WebPartsDemo.aspx 页。

  5. 切换到 “源” 视图。

  6. 在 <SidebarZone 的 asp:webpartzone> 元素中,在对用户控件的引用正上方,添加包含 <链接的 asp:label> 元素,如以下示例所示。 此外,将 Title 属性添加到用户控件标记,其值为 Search,如下所示。

    <asp:WebPartZone id="SidebarZone" runat="server"
                     headertext="Sidebar">
        <zonetemplate>
            <asp:label runat="server" id="linksPart" title="My Links">
                <a href="http://www.asp.net">ASP.NET site</a>
                <br />
                <a href="http://www.gotdotnet.com">GotDotNet</a>
                <br />
                <a href="http://www.contoso.com">Contoso.com</a>
                <br />
            </asp:label>
            <uc1:SearchUserControl id="searchPart"
              runat="server" title="Search" />
        </zonetemplate>
    </asp:WebPartZone>
    
  7. 保存并关闭该文件。

现在,可以通过在浏览器中浏览到页面来测试页面。 该页显示这两个区域。 以下屏幕截图显示了页面。

包含两个区域的 Web 部件演示页

Web 部件 VS 演练 1 屏幕截图

图 3:Web 部件 VS 演练 1 屏幕截图

在每个控件的标题栏中,都有一个向下箭头,用于访问可对控件执行的可用操作的谓词菜单。 单击其中一个控件的谓词菜单,然后单击 “最小化 ”谓词,并注意该控件已最小化。 在谓词菜单中,单击“ 还原”,控件将返回到其正常大小。

使用户能够编辑页面和更改布局

Web 部件允许用户通过将 Web 部件控件从一个区域拖动到另一个区域来更改其布局。 除了允许用户将 WebPart 控件从一个区域移到另一个区域外,还可以允许用户编辑控件的各种特征,包括其外观、布局和行为。 Web 部件控件集为 WebPart 控件提供基本的编辑功能。 尽管在本演练中不会执行此操作,但还可以创建自定义编辑器控件,以允许用户编辑 WebPart 控件的功能。 与更改 WebPart 控件的位置一样,编辑控件的属性依赖于 ASP.NET 个性化来保存用户所做的更改。

在本演练的这一部分,你将添加用户编辑页面上任何 WebPart 控件的基本特征的功能。 若要启用这些功能,请将另一个自定义用户控件添加到页面,以及一个 <asp:editorzone> 元素和两个编辑控件。

创建支持更改页面布局的用户控件

  1. 在 Visual Studio 的“ 文件 ”菜单上,选择“ 新建 ”子菜单,然后单击“ 文件 ”选项。

  2. “添加新项 ”对话框中,选择“ Web 用户控件”。 将新文件命名为 DisplayModeMenu.ascx。 取消选择“ 将源代码放在单独的文件中”选项。

  3. 单击“添加”创建新控件。

  4. 切换到 “源” 视图。

  5. 删除新文件中的所有现有代码,并粘贴以下代码。 此用户控件代码使用 Web 部件控件集的功能,这些功能使页面能够更改其视图或显示模式,并且还可以在处于某些显示模式时更改页面的物理外观和布局。

    <%@ Control Language="C#" ClassName="DisplayModeMenuCS" %>
    
    <script runat="server">
    
        // Use a field to reference the current WebPartManager control.
        WebPartManager _manager;
        void Page_Init(object sender, EventArgs e) {
            Page.InitComplete += new EventHandler(InitComplete);
        }
        void InitComplete(object sender, System.EventArgs e) {
            _manager = WebPartManager.GetCurrentWebPartManager(Page);
            String browseModeName = WebPartManager.BrowseDisplayMode.Name;
            // Fill the drop-down list with the names of supported display modes.
            foreach (WebPartDisplayMode mode in
            _manager.SupportedDisplayModes) {
                String modeName = mode.Name;
                // Make sure a mode is enabled before adding it.
                if (mode.IsEnabled(_manager)) {
                    ListItem item = new ListItem(modeName, modeName);
                    DisplayModeDropdown.Items.Add(item);
                }
            }
            // If Shared scope is allowed for this user, display the
            // scope-switching UI and select the appropriate radio
            // button for the current user scope.
            if (_manager.Personalization.CanEnterSharedScope) {
                Panel2.Visible = true;
                if (_manager.Personalization.Scope ==
                PersonalizationScope.User)
                    RadioButton1.Checked = true;
                else
                    RadioButton2.Checked = true;
            }
        }
    
        // Change the page to the selected display mode.
        void DisplayModeDropdown_SelectedIndexChanged(object sender,
            EventArgs e) {
            String selectedMode = DisplayModeDropdown.SelectedValue;
            WebPartDisplayMode mode =
                _manager.SupportedDisplayModes[selectedMode];
            if (mode != null)
                _manager.DisplayMode = mode;
        }
        // Set the selected item equal to the current display mode.
        void Page_PreRender(object sender, EventArgs e) {
            ListItemCollection items = DisplayModeDropdown.Items;
            int selectedIndex =
            items.IndexOf(items.FindByText(_manager.DisplayMode.Name));
            DisplayModeDropdown.SelectedIndex = selectedIndex;
        }
        // Reset all of a user's personalization data for the page.
        protected void LinkButton1_Click(object sender, EventArgs e) {
            _manager.Personalization.ResetPersonalizationState();
        }
        // If not in User personalization scope, toggle into it.
        protected void RadioButton1_CheckedChanged(object sender, EventArgs e) {
            if (_manager.Personalization.Scope == PersonalizationScope.Shared)
                _manager.Personalization.ToggleScope();
        }
    
        // If not in Shared scope, and if user has permission, toggle
        // the scope.
        protected void RadioButton2_CheckedChanged(object sender,
        EventArgs e) {
            if (_manager.Personalization.CanEnterSharedScope &&
                _manager.Personalization.Scope == PersonalizationScope.User)
                _manager.Personalization.ToggleScope();
        }
    </script>
    
    <div>
        <asp:Panel ID="Panel1" runat="server"
          BorderWidth="1" Width="230" BackColor="lightgray"
            Font-Names="Verdana, Arial, Sans Serif">
            <asp:Label ID="Label1" runat="server"
              Text=" Display Mode" Font-Bold="true"
                Font-Size="8" Width="120" />
            <asp:DropDownList ID="DisplayModeDropdown"
              runat="server" AutoPostBack="true" Width="120"
                OnSelectedIndexChanged="DisplayModeDropdown_SelectedIndexChanged" />
            <asp:LinkButton ID="LinkButton1" runat="server"
                 Text="Reset User State"
                 ToolTip="Reset the current user's personalization data for the page."
                 Font-Size="8" OnClick="LinkButton1_Click" />
            <asp:Panel ID="Panel2" runat="server"
                GroupingText="Personalization Scope" Font-Bold="true"
                Font-Size="8" Visible="false">
                <asp:RadioButton ID="RadioButton1" runat="server"
                    Text="User" AutoPostBack="true"
                    GroupName="Scope"
                    OnCheckedChanged="RadioButton1_CheckedChanged" />
                <asp:RadioButton ID="RadioButton2" runat="server"
                    Text="Shared" AutoPostBack="true"
                    GroupName="Scope"
                    OnCheckedChanged="RadioButton2_CheckedChanged" />
            </asp:Panel>
        </asp:Panel>
    </div>
    
  6. 通过单击工具栏上的保存图标或选择“文件”菜单上的“ 保存 ”来保存 文件

使用户能够更改布局

  1. 打开 WebPartsDemo.aspx 页,并切换到 “设计” 视图。

  2. 将插入点置于“ 设计 ”视图中的前面添加的 WebPartManager 控件的后面。 在文本后面添加硬返回,以便 WebPartManager 控件后有一个空白行。 将插入点放在空白行上。

  3. 将刚创建的用户控件 (名为 DisplayModeMenu.ascx) 的文件拖到 WebPartsDemo.aspx 页中,并将其放在空白行上。

  4. 将 EditorZone 控件从工具箱的 WebParts 部分拖到 WebPartsDemo.aspx 页中剩余的打开表单元格。

  5. 从“工具箱”的“ WebParts ”部分,将“AppearanceEditorPart”控件和 LayoutEditorPart 控件拖到 EditorZone 控件中。

  6. 切换到 “源” 视图。 表单元格中生成的代码应类似于以下代码。

    <td valign="top">
        <asp:EditorZone ID="EditorZone1" runat="server">
            <ZoneTemplate>
                <asp:AppearanceEditorPart ID="AppearanceEditorPart1"
                  runat="server" />
                <asp:LayoutEditorPart ID="LayoutEditorPart1"
                  runat="server" />
            </ZoneTemplate>
        </asp:EditorZone>
    </td>
    
  7. 保存 WebPartsDemo.aspx 文件。 你已创建一个允许用户更改显示模式和更改页面布局的用户控件,并且已在主网页上引用了该控件。

现在可以测试编辑页面和更改布局的功能。

测试布局更改

  1. 在浏览器中加载页面。
  2. 单击 “显示模式 ”下拉菜单,然后选择“ 编辑”。 将显示区域标题。
  3. 按标题栏将 “我的链接” 控件从“边栏”区域拖到“主”区域底部。 页面应如以下屏幕截图所示。

Web 部件 VS 演练 2 屏幕截图

图 4:Web 部件 VS 演练 2 屏幕截图

  1. 单击 “显示模式 ”下拉菜单,然后选择“ 浏览”。 页面将刷新,区域名称消失,并且 “我的链接” 控件将保留在你放置它的位置。

  2. 若要演示个性化设置是否有效,请关闭浏览器,然后再次加载页面。 所做的更改将保存以供将来的浏览器会话使用。

  3. “显示模式 ”菜单中,选择“ 编辑”。

    页面上的每个控件现在在其标题栏中显示一个向下箭头,其中包含谓词下拉菜单。

  4. 单击箭头以显示 “我的链接” 控件上的谓词菜单。 单击 “编辑” 谓词。

    此时将显示 EditorZone 控件,其中显示了添加的 EditorPart 控件。

  5. 在编辑控件的“ 外观 ”部分中,将 “标题 ”更改为“我的收藏夹”,使用 Chrome 类型 下拉列表选择“ 仅标题”,然后单击“ 应用”。 以下屏幕截图显示了处于编辑模式的页面。

处于编辑模式的 Web 部件演示页

Web 部件 VS 演练 3 屏幕截图

图 5:Web 部件 VS 演练 3 屏幕截图

  1. 单击“ 显示模式 ”菜单,然后选择“ 浏览 ”以返回到浏览模式。
  2. 控件现在具有更新的标题,没有边框,如以下屏幕截图所示。

编辑的 Web 部件演示页

Web 部件 VS 演练 4 屏幕截图

图 4:Web 部件 VS 演练 4 屏幕截图

在运行时添加 Web 部件

还可以允许用户在运行时将 Web 部件控件添加到其页面。 为此,请使用 Web 部件目录配置页面,该目录包含要提供给用户的 Web 部件控件的列表。

允许用户在运行时添加 Web 部件

  1. 打开 WebPartsDemo.aspx 页,并切换到 “设计” 视图。

  2. 从“工具箱”的“ Web 部件 ”选项卡中,将 CatalogZone 控件拖到表的右列中,在 EditorZone 控件下。

    这两个控件可以位于同一个表单元格中,因为它们不会同时显示。

  3. 在“属性”窗格中,将字符串 Add Web Parts 分配给 CatalogZone 控件的 HeaderText 属性。

  4. 从“工具箱”的 “WebParts ”部分,将 DeclarativeCatalogPart 控件拖动到 CatalogZone 控件的内容区域中。

  5. 单击 DeclarativeCatalogPart 控件右上角的箭头以公开其“任务”菜单,然后选择“ 编辑模板”。

  6. 从“工具箱”的“标准”部分,将 FileUpload 控件和 Calendar 控件拖动到 DeclarativeCatalogPart 控件的 WebPartsTemplate 部分。

  7. 切换到 “源” 视图。 检查 asp:catalogzone> 元素的<源代码。 请注意,DeclarativeCatalogPart 控件包含一个 webpartstemplate> 元素,其中包含两个<封闭的服务器控件,这些控件可从目录添加到页面。

  8. 使用下面代码示例中为每个标题显示的字符串值,将 Title 属性添加到添加到目录的每个控件。 尽管标题不是通常在设计时可以在这两个服务器控件上设置的属性,但当用户在运行时将这些控件从目录添加到 WebPartZone 区域时,它们都包装有一个 GenericWebPart 控件。 这使它们能够充当 Web 部件控件,因此它们能够显示标题。

    DeclarativeCatalogPart 控件中包含的两个控件的代码应如下所示。

    <asp:DeclarativeCatalogPart ID="DeclarativeCatalogPart1" runat="server">
        <WebPartsTemplate>
            <asp:Calendar ID="Calendar1" runat="server" title="My Calendar" />
            <asp:FileUpload ID="FileUpload1" runat="server" title="Upload Files" />
        </WebPartsTemplate>
    </asp:DeclarativeCatalogPart>
    
  9. 保存页。

现在可以测试目录。

测试 Web 部件目录

  1. 在浏览器中加载页面。

  2. 单击 “显示模式 ”下拉菜单,然后选择“ 目录”。

    将显示标题为 “添加 Web 部件 ”的目录。

  3. “我的收藏夹” 控件从“主”区域拖回“边栏”区域的顶部,然后将其拖放到该区域。

  4. “添加 Web 部件”目录中,选择检查框,然后从包含可用区域的下拉列表中选择“”。

  5. 单击目录中的 “添加 ”。 控件将添加到主区域。 如果需要,可以将目录中的多个控件实例添加到页面。

    以下屏幕截图显示了包含文件上传控件和“主”区域中的日历的页面。

从目录添加到主区域的控件

图 5:从目录 6 添加到主区域的控件。单击“ 显示模式 ”下拉菜单,然后选择“ 浏览”。 目录消失,页面将刷新。 7. 关闭浏览器。 再次加载页面。 所做的更改将保留。