原代码下载: WebParts.exe (619KB)
原文出处: ASP.NET 2.0 Personalize Your Portal with User Controls and Custom Web Parts
本文基于 ASP.NET 2.0 的预发行版本,文中提供的所有信息将来都可能发生变化。
本文将讨论以下内容:
使用Web部件创建模块化的Web门户应用;
个人化特性和自定义特性;
将自定义用户控件作为Web部件使用;
创建一个个人化特性的提供程序;
现今门户应用非常流行,好的门户都有共同而显著的特点。那就是都会给访问者提供雅观的信息,并且这些信息都是通过模块化的、一致的、易于浏览的用户界面提供的。一些综合性的门户网站走得更远,它们甚至允许网站成员提供内容、上传文档以及个人化门户页面。
微软为 Windows Server 2003 平台增加了一个可扩展的门户应用框架,随之发布了一个 Windows SharePoint 服务 ,这个框架提供了门户应用框架必须的一些基本元素,其中包括站点成员的支持、内容和文档管理、使用 Web 部件以模块化的形式展示数据等等。
Web 部件提供了支持自定义特性和个人化特性的基础功能。在Windows SharePoint服务网站里面,通过配置站点,门户应用的用户能够添加、配置、删除Web部件,这样他们就能轻松地个人化或者定制页面了。基于Windows SharePoint服务的站点还提供了一种简便而且强大的方法扩展站点的功能,那就是:开发自定义Web部件。创建支持定 制特性和个人化特性的Web部件时,你只需要简单地在你的Web部件类里面增加一些属性以及设置几个特殊的标签就可以了。那些繁琐复杂的工作都由 Windows Sharepoint 服务的Web部件基础结构来完成,比如:序列化、存储和读取与站点自定义特性和成员个人化特性相关的数据。
ASP.NET 2.0 引入了一套Web部件控件集,这套控件集与 Windows SharePoint 服务提供的功能很相似,它们 被设计用来完成序列化、存储和读取站点自定义特性和成员个人化特性相关数据等功能。但是它们更独特和更灵活,它们与 SQL Server 或 Active Directory 不是紧耦合的。对于那些希望使用基于表单验证技术建立门户,或者不想受限于某一特定数据库解决方案的公司来讲,这无疑是一个好消息。
图1:使用模块化Web部件设计的一个示例门户应用
本文将向你展示一个用 ASP.NET 2.0 Web 部件开发的示例门户应用,其主要目的是让你了解为门户应用开发Web部件时 ,你将面临的一些重要的设计问题。首先,我们将着重介绍新的 ASP.NET 2.0 Web部件控件集涉及的一些基本概念和控件类型。例子参见图1。
Web部件基础
用来放置Web部件的页面,我们可以称之为Web部件页面。如图2所示,一个Web部件页面需要一个WebPartManager 控件(只能有一个)和一个或多个的 WebPartZone 控件。还可以包括一个 EditorZone 控件或者 CatalogZone 控件(不是必需的)。需要注意的是,在.aspx文件中,WebPartManager 控件的标签必须出现在与Web部件 基础结构相关的任何其它控件标签之前,比如:WebPartZone 控件、EditorZone 控件、CatalogZone 控件。为了更好地控制Web部件页面的布局和表现形式,你还可以在aspx文件中使用HTML表格,将不同的 zone 控件布局到不同的地方。
图2:一个Web部件页面的典型布局
我们先来看一个简单的Web部件页面例子,该页面包含 WebPartManager 控件和 WebPartZone 控件:
在页面里放置了一个 WebPartZone 控件之后,就可以使用Web部件定义来创建Web部件实例了。有二种不同的方法可以创建Web部件定义。第一种方法是创建一个从 WebPart 类继承的类,第二种方法是创建一个用户控件。 本文稍后的部分,我们将详细探讨这两种方法之间的不同。现在,我们先创建一个从WebPart类继承的简单的类(参见图3)。
每个Web部件实例都存在于一个页面特定的 WebPartZone 控件的某个索引位置上。一个 WebPartZone 控件可以包含多个Web部件。如图4所示,在 WebPartZone1 控件里面有二个Web部件实例。
图4:在一个特定zone控件中的Web部件
你可以通过编程方式和声明方式将Web部件添加到某个区(zone)中。稍后你还可以看到如何将Web部件添加到部件目录中。当你创建了一个 CatalogPart 控件以后,用户就可以在运行时将一个新的Web部件添加到WebPartZone控件中。
以编程方式将Web部件添加到 WebPartZone 控件里面的方法取决于需要添加的Web部件的类型。如果是一个从 WebPart 继承的类,需要以编程方式创建一个 该类的实例,然后调用 WebPartManager 类的 AddWebPart 方法。调用 AddWebPart 方法时,你需要传入的参数包括:Web部件的实例、 目标 WebPartZone 控件、以及Web部件在 WebPartZone 控件中的索引位置。代码如下:
// create Web Part instance from WebPart-derived class
WebPart wp1 = new WingtipWebParts.HelloWorld();
WebPartManager1.AddWebPart(wp1, WebPartZone1, 0);
此即通过编程方式将Web部件添加到 WebPartZone。声明方式是在Web部件页面的.aspx文件中定义控件标签。当用户访问页面时,如果你希望某个Web部件出现在特定的 WebPartZone 控件中,你可以在 WebPartZone控件中添加一个 ZoneTemplate。代码如下:
<%@ Register Assembly="WingtipWebParts" Namespace="WingtipWebParts"
TagPrefix="Wingtip" %>
别忘了给Web部件“打扮”一下,因为如果不这样的话,你的Web部件看起来会很乏味的。内联门户网应用需要的一个通用特性就是能够给站点“换肤”,根据访问者的喜好改变Web部件的 外观。过去,这意味着你要自己创建一套架构去支持改变控件呈现方式的功能,而这需要做大量的工作。ASP.NET 2.0 引入了“主题”的概念,其中包括一系列的风格属性和控件属性,这些属性可以应用到单个控件、整个页面甚至整个应用的全局范围。
为了让你的门户应用看起来显得优雅和专业,你需要定制所有 WebPartZone 控件、EditorZone 控件和 CatalogZone 控件的 外观。当你刚开始做这件事的时候,你会觉得这种工作非常乏味。因为你需要给Web部件、Editor部件以及Catelog部件的内容区、标题栏和动态菜单等等区域换肤和修改显示属性。幸运的是,新的ASP.NET 2.0 的主题特性可以将这些.aspx文件中有关界面工作的成果提取到可以重用的.skin文件和.css文件中。这篇文章的示例门户应用程序就是使用换肤和主题功能来定制Web部件的 外观的,你可以到MSDN杂志的网站上下载。
显示模式和页面范围
WebPartManager 控件的一个单一实例运行在每个Web部件页面中,它负责管理Web部件实例以及Web部件如何与WebPartZone控件交互。 WebPartManager控件还提供了一个可编程接口,可以用来切换Web部件页面的显示模式,例如:你可以在以下 三种模式之间切换:浏览模式、设计模式和编辑模式。例如:要通过程序将当前页面切换到设计模式,你只需要添加一个链接控件,在这个控件的事件处理程序中将 DisplayMode属性设置为DesignDisplayMode即可。代码如下:
WebPartManager1.DisplayMode = WebPartManager.DesignDisplayMode;
理解Web部件页面每种显示模式之间的区别是很重要的。默认情况下,Web部件页面处于浏览模式,此模式不允许用户修改任何的Web部件。当切换到设计模式的时候,用户就能够在WebPartZone内部或者不同的 区之间移动Web部件了。图5列出了所有的显示模式。
ASP.NET 2.0 Web部件控件会在后台生成所有必需的DHTML和Javascript代码,让用户在浏览器里可以进行拖放操作。在不支持必 需的DHTML和Javascript特性的浏览器里,除了拖放操作之外的所有其它编辑功能都可以使用。这意味着你不必担心要强制所有的客户使用 Microsoft IE5.0或以上的浏览器。ASP.NET 2.0 Web部件控件还支持管理个人化数据的存储和获取,能够记住用户上一次将Web部件放在了什么地方。
除了支持使用代码切换显示模式之外,WebPartManager控件还提供了允许Web部件页面在用户范围和共享范围之间切换的方法。页面范围是指 对Web部件的修改是自定义操作还是个人化操作。所有的用户都能看到自定义操作的结果,而只有用户自己才能看到个人化操作的结果。改变Web部件页面的范 围可以通过调用WebPartManager 控件的 ToggleScope 方法来实现,代码如下:
WebPartManager1.Personalization.ToggleScope();
默认范围即用户范围,也就是说对Web部件的修改被记录为个人化操作,只能被当前用户看到。成功地调用ToggleScope方法会把Web部件页面 改变到共享范围,这样的话,对Web部件的修改就会被记录为自定义操作。共享范围的作用是为了允许管理员或者站点设计人员统一修改Web部件页面中的 Web控件,让所有用户都能看到这种改变。如果有冲突,个人化修改总是优先于全局自定义操作。
当前用户并不总是能够成功地进入共享范围。默认情况下,任何用户都没有这样的权限。只有在Web.config文件中用户被赋予了这样的权限才行。下 面是一个例子,它允许所有拥有admin或者site_designer角色的用户可以进入共享范围和修改全局自定义数据:
属性和个人化
每一个Web部件对象都有一套标准的属性能够被自定义或者个人化。例如,每个Web部件都有一个Title属性,在被加入WebPartZone之后,还能够被自定义。EditorZone控件和一些Editor部件允许用户对Web部件属性做修改。
当用户将Web部件页面切换为编辑模式时,Web部件的菜单提供了一个编辑命令。在一个Web部件上调用编辑命令会显示出一个EditorZone控件,此控件是放在相关的 区控件中的。ASP.NET 2.0提供了一些内置的Editor部件,用来修改标准的Web部件外观、行为和布局。
通过添加一些能够被个人化的自定义属性,Web部件个人化配置数据能够被轻松地扩展。你只需要在Web部件类的定义里面添加这些属性,并且打上诸如: Personalizable、WebBrowsable、WebDisplayName之类的特性标签就可以了。当你完成这些之后,Web部件控件会帮 助你存储和获取这些被个人化或者自定义的属性值。
当你创建某个个人化属性时,通常会同时定义一个私有字段,代码如下:
private bool _HR = true;
[Personalizable(PersonalizationScope.User), WebBrowsable, WebDisplayName("
Show HR News"), WebDescription("
Use this property to show/hide HR news")]
public bool HR { get { return _HR; } set { _HR = value; } }
如果你想允许你的用户像这样个人化某个属性,你只需要在当前页面的EditorZone控件中添加一个PropertyGridEditorPart部件就可以了。图6显示了当你这样做的时候,用户会看到什么:
图6 Editor 部件允许用户个人化 Web 部件
如果你定义的某个Web部件属性是字符串或者数字类型的,PropertyGridEditorPart 部件会提供一个文本框让用户修改属性值。如果这个属性是布尔类型的,PropertyGridEditorPart部件会提供一个 复选框,如图6所示。
图7给出了从 Windows SharePoint 服务Web组件开发中学来的一个极好的编程技巧:你可以定义一个基于枚举类型的个人化属性。
创建 WebBrowsable 以及基于枚举类型的个人化的属性,其真正价值在于 PropertyGridEditorPart 部件会生成一个包括所有可选属性值的下拉列表,正如图7中显示的 Timeframe 属性那样。对用户来说,这很方便,而且有助于保证用户选择一个有效的属性值。
关于 Timeframe 属性,还有一件事值得留意。它被加上了一个 Personalizable 特性,特性的值为PersonalizationScople.Shared。当属性像这样被定义为共享属性的时候,它只能被自定义,而不可以个人化。既 然共享属性不能被个人化,当当前页面在用户范围的时候,PropertyGridEditorPart 部件不会显示这个属性,而只会在共享范围显示这个属性。