一、引言

 
如今,软件开发正由 OO 时代进入到“面向组件的开发”时代。 Visual Basic ASP.NET 这样一些编程工具之所以越来越流行,其主要原因在于:使用可视化方式描述对象更贴近自然,也因此进一步提高了软件的生产效率。另一方面,通过这种方式,开发人员能够以其自己特有的方式(如以 .dll .ascx 等文件形式)来创建和发布控件,从而极大地方便了广大软件开发者。
 
借助于组件 ( 非可视化对象 ) 和控件 ( 可视化对象 ) ,我们可以重用这些软件元件所具有的功能,并最终创建出更高效的应用程序。
 
在上一世纪九十年代前后的 Web 世界中,所谓“动态的网页”,也就是每隔几周才更新一次的静态 Web 页面罢了。到九十年代后期,终端开发用户的动态内容的概念开始转变为使用服务器端处理技术,例如,当一个用户向他们的网站发出一个请求时,使用动态服务器页面来生成一个 HTML 页面。
 
随着 Web 应用程序用户对 Web 的理解越来越深入,他们的用户体验期望经历了巨大的变化。特别是,最近发展起来的 AJAX 现象又进一步加快了 Web 应用程序的这种动力和交互性,而终端用户开始能够尝试到这种体验,甚至能够根据自己的要求“裁剪”这种体验。
 
在本文中,我们先简单回顾一下 ASP.NET Web Parts 的粗略架构;然后,我们着手创建一个定制的 Web Part 控件,从而领略一下 ASP.NET 2.0 为进一步扩展创建定制服务器控件的技术。
 
二、 ASP.NET Web Parts架构
 
Web Part 提供了一种对我们已习惯的 ASP.NET 控件模型的扩 展— 添加重要的定制和个性化方面,以及那些能够在运行时刻由开发者或应用程序用户决定的方面。
 
用户能够在运行时刻决定哪一部分 Web Part 将会出现在他们的个性化的 Web 页面实例上,以及这些内容看起来的样子。
 
为了支持这一 ASP.NET 特征,开发者必须首先创建 .ASPX 页面形式的 Web 面—它们将 包含 Web Part 并且与用户进行交互以便他们能够在运行时刻作出自己所希望的选择。
 
【重要结论】一个宿主ASP.NET 2.0 Web Part.ASPX页面必须包含且仅包含一个WebPartManager控件以及一个或多个WebPartZone控件的实例。
 
其中,这个 WebPartManager 控件能够为你的页面使用 Web Part 提供基层框架支持,而 WebPartZone 用于定义能够包含 Web Part 的页面中的区域。这些区域(即“ Zone ”)用于把页面组织成此页面中的一些相关联的块。
 
WebPartZone 控件之外,还存在另外两个 ASP.NET 开发者可自由使用的 Zone CatalogZone EditorZone 控件。
 
一个 CatalogZone 用作一个容器,用于枚举可用在某页面中的 Web Part 控件;而 EditorZone 控件中包含一个编辑 器— 用户将调用之来设置包括在他们的 Web 页面上的 Web Part 中的属性。
 
下图 1 展示了一个使用 Web Part 控件的 .ASPX 页面的一般架构。而图 2 则展示了这一架构在实际中的使用情形。
 
 
 
1.一个使用Web Part控件的.ASPX页面的一般架构
 
注意,下图 2 中的页面上有两个可见的带( Zone ),一个包含左边栏目,另一个包含右边栏目。其中,高亮区域是单个 Web Part
 
 
 
2. 实际使用Web Part 控件的.ASPX 页面情况
 
点击上图 2 中的“ Add stuff ”链接后可以使一个目录带看起来如下 3 所示。
 
 
3.目录区带看上去的样子
在此,用户可以选择需要的 Web Part 件—该控件 提供他们选择的内容或功能,例如收集自各种数据源的 RSS 回馈数据等。
 
如果用户点击其中一个特定 Web Part 上的“ Edit ”链接(例如图 3 中的高亮区带),则将出现相应于一个 Part 特定的编辑器。
 
Part 特定的编辑器可以包含开发者认为适当的任何用户定制。用户可以从中选择要显示多少项,以及是否显示指定图像等。
 
当启动“ Edit ”模式时, Web Part 能够围绕着一个 Web Part Zone 或在两个区带间移动。此外, Web Part 还能够被连接到 Part 间建立的属性绑定。例如,一个 Web Part 的属性可以用于约束在一个不同的 Web Part 上显示的数据。
 
【重要结论】任何ASP.NET控件都能够不经任何修改用作一个Web Part。例如,任何现有的ASP.NET控件、用户控件或定制控件都能够简单地拖放到一个Web Part Zone 中的一个.ASPX页面中。
 
注意,这个“拖放”将引起一个对 WebPartManager CreateWebPart() 的隐式调用 —此方法 将创建一个 GenericWebPart 对象实例并且使用你添加到页面中的控件来初始化这个 GenericWebPart 对象。你可以在设计时刻或运行时刻动态地使用任何标准控件作为一个 Web Part
 
因此,一旦我们搞清楚了所谓的“ Zone 架构”,那么,使用 Web Part 进行 Part 开发则非常类似于使用 Visual Studio 进行的任何其它可视化控件开发。而且,创建定制的 Web Part 与开发定制 ASP.NET 控件之间存在很大相似之处—创建定制的 Web Part 需要继承自 WebPart 类,而创建定制 ASP.NET 控件需要继承自 Control 类。
 
三、 创建定制的Web Part
 
WebParts 控件组出现之前,尽管开发者也可以模拟现在 Web Part 所具有的大多数功能;但是,开发者必须在后台以编程方式添加大量的属性—例如在一个 Web Part 中所频繁使用的 GenericWebPart 属性。尽管这种方法完全可 ;但是如今,构建包括这种功能的 Web 应用程序的开发者却逐渐趋向于先构建全面支持“ Web Part ”功能的控件—然后再把这些“积木块”应用于 Web 页面开发。
 
就象创建标准 ASP.NET 控件一样,创建定制的 Web Part 控件也存在两种典型的方法—用户 Web Part 和定制 Web Part
 
(一)第一种方法—继承自基类 WebPart
 
我们可以创建一个继承自基类 WebPart 的定制控件。这种方法的一大优点是:这类控件能够被编译成一个二进制 .DLL 文件,而且该 .DLL 可安装到全局程序集缓存 (GAC) 中。
 
此时,我们的类可能看起来如下面的列表 1 所示。
 
列表 1 —定制Web Part的典型代码
 

          
          
Imports System.ComponentModel
Imports System.Web.UI
<{0}:SampleControl runat="server">")>
Public Class SampleControl
Inherits System.Web.UI.WebControls.WebParts.WebPart
Private strSubtitle As String
Private _Title As String = "我的WebPart"
Public Sub New()
strSubtitle = "关于" & Now.ToString
Me.TitleIconImageUrl = "mySampleIcon.gif"
End Sub
Private Sub BookDisplay_Init(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Init
MyBase.HelpUrl = " [url]http://www.example.net/myWebPartHelp.htm[/url]"
End Sub
Public Overrides Property Title() As String
Get
Return MyBase.Title
End Get
Set(ByVal value As String)
MyBase.Title = _Title
End Set
End Property
Public Overrides ReadOnly Property Subtitle() As String
Get
Return strSubtitle
End Get
End Property
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
MyBase.Render(writer)
End Sub
End Class
 
在构建编译控件时, .DLL 形式使得控件的发布非常容易,而且此控件的应用范围不并局限于定义它们的应用程序;但遗憾的是,以这种方式构建的控件却缺乏可视化的设计体验。
(二)第二种方法—用户控件+实现 IWebPart 接口
 
下面,我们将集中讨论第二种途径—构建 UserControl 风格的 Web Part 。我们可以通过创建一个 ASP.NET 用户控件并实现 IWebPart 接口来创建一个用户 Web Part 。列表 2 展示了一个实现了 IWebPart 接口的 Web Part 类的框架。
 
列表 2 —以实现IWebPart接口途径创建的用户Web Part典型代码
 

          
          
Class myWebUserControl
Inherits System.Web.UI.UserControl
Implements IWebPart
Private _CatalogIconImageUrl As String = "images/5PointStar.gif"
Public Property CatalogIconImageUrl() As String Implements
System.Web.UI.WebControls.WebParts.IWebPart.CatalogIconImageUrl
Get
Return _CatalogIconImageUrl
End Get
Set(ByVal value As String)
_CatalogIconImageUrl = value
End Set
End Property
'描述
Private _Description As String = "【定制Web Part】"
Public Property Description() As String Implements
System.Web.UI.WebControls.WebParts.IWebPart.Description
Get
Return _Description
End Get
Set(ByVal value As String)
_Description = value
End Set
End Property
'副标题
Private _Subtitle As String = ""
Public ReadOnly Property Subtitle() As String Implements
System.Web.UI.WebControls.WebParts.IWebPart.Subtitle
Get
Return _Subtitle
End Get
End Property
'标题
Private _Title As String = "【我的定制Web Part】"
Public Property Title() As String Implements
System.Web.UI.WebControls.WebParts.IWebPart.Title
Get
Return _Title
End Get
Set(ByVal value As String)
_Title = value
End Set
End Property
' TitleIconImageUrl
Private _TitleIconImageUrl As String = "images/5PointStar.gif"
Public Property TitleIconImageUrl() As String Implements
System.Web.UI.WebControls.WebParts.IWebPart.TitleIconImageUrl
Get
Return (_TitleIconImageUrl)
End Get
Set(ByVal value As String)
_TitleIconImageUrl = value
End Set
End Property
' TitleUrl
Private _TitleUrl As String = " [url]http://www.example.com[/url]"
Public Property TitleUrl() As String Implements
System.Web.UI.WebControls.WebParts.IWebPart.TitleUrl
Get
Return _TitleUrl
End Get
Set(ByVal value As String)
_TitleUrl = value
End Set
End Property
End Class
 
接下来,我们需要在我们的定制用户控件上添加可视化元素。在本示例中,我们将添加三个文本 框—它们结合在一起形成 我们的定制控件;当然,你也可以使用任何其它 ASP.NET 控件。
 
【提示】尽管这是一个 Web Part ,但是,它本质上还是一个 ASP.NET 用户控件;所以,你可以在此封装你想实现的任何功能。
 
现在,对于该控件中的每一个用户接口部件—我们想使终端用户在运行时刻能够配置它 们。为此, 我们必须在此控件中定义一个布尔指示器,用于根据用户的选择决定是否应该显示该元素。
 
于是,每一个部件看起来具有如下形式:
 

        
        
Protected _PropertyONE As Boolean = True

WebDisplayName("显示第一项内容"), _
WebDescription("使用该属性来显示/隐藏第一项内容")> _
Public Property PropertyONE() As Boolean
Get
Return _PropertyONE
End Get
Set(ByVal value As Boolean)
_PropertyONE = value
End Set
End Property
 
【注意】这里的属性被标记为“ Personalizable ”。借助于这个系统提供的属性,在修改该属性时,属性的状态将会被自动地保存。另外,该属性还被标记为“ WebBrowsable ”;这样以来,我们就可以在一个类似于 PropertyGridEditorPart (这个控件与 AppearanceEditorPart BehaviorEditorPart LayoutEditorPart 控件及它们共同的容器控件 EditorZone 共同构成个性化 Web Part 页面的“五剑客”)的设计器中修改它。
默认情况下,被标记为“ Personalizable ”属性的值将会被保存到一个位于你的应用程序的根文件 夹( App_Dat a 下的 Microsoft SQL Server 2005 Express 数据库( ASPNETDB.MDF )表格中。当然,你也可以修改此个性化数据所存储的位 置—通过 修改你的应用程序的 Web 配置文件实现。
 
对于与特定用户相关联的特定值, ASP.NET 框架必须能够识别这个当前用户。你还可以在 Windows 和表单认证 (Windows 认证是缺省的认证方式 ) 中使用个性化设置。当使用表单认证时,在用户请求页面之前,此用户必须先被认证。因为 ASP.NET 2.0 针对会员实现了“提供者模型”;所以,你可以使用任何可用的会员提供者程序。
另一方面,上面 WebDisplayName WebDisplayDescription 两个属性被自动地应用于我们的 WebPartEditor 。每一个属性的 Boolean 值都将会根据 Web Part 属性编辑器中的复选框进行设置。
 
对于每一个我们想由用户配置的用户接口元素定义了一个 WebBrowsable 属性之后,接下来, 页面加载中设置任何用户选择的元素的“ Visible ”属性之前,我们就可以简单地使用这些属性。
 

        
        
Protected Sub Page_PreRender(ByVal sender As Object,ByVal e
As System.EventArgs) Handles Me.PreRender
TextBox1.Visible = PropertyONE
TextBox2.Visible = PropertyTWO
TextBox3.Visible = PropertyTHREE
End Sub
 
(二)测试定制的 Web Part 控件
 
现在,我们的基本 Web Part 已经准备好待用;所以,我们可以构建一个简单的 .ASPX 容器来测试我们的 Web Part
 
为此,我们需要构建一个包含一个 WebPartManager 、一个 WebPartZone 和一个 EditorZone .ASPX 页面。
 
Visual Studio 的方案资源管理器中,我们可以拖动我们的定制控件相应的 .ASCX 文件,并且把它投放到 WebPartZone 上。
 
然后,我们再从 WebParts 工具箱中把一个 WebPartEditorZone 控件拖动到我们的页面的 EditorZone 上面。
 
【注意】 WebPartZone 控件提供了一组丰富的属性以便我们美化控件界面。例如,在我们的演示应用程序中,我们已经设置了相应的属性用于添加颜色和边界为显示的缺省菜单(当用户配置 Web Part 时)。
 
在我们能够运行这个应用程序之前,还需要加入一项功能—我们需要提供给用户一种方法用于切入 / 切出“ Edit ”模式。
 
为此,我们仅把一个按钮控件添加到我们的 Web 表单上,并且在它的 Click 事件处理器中相应地设置我们的 WePartManager DisplayMode 属性。
 

        
        
Protected Sub Button1_Click(ByVal sender As Object,ByVal e As _
System.EventArgs) Handles Button1.Click
If Not WebPartManager1.DisplayMode Is _
WebPartManager.EditDisplayMode Then
WebPartManager1.DisplayMode = WebPartManager.EditDisplayMode
Button1.Text = "设置编辑模式为Off"
Else
WebPartManager1.DisplayMode = WebPartManager.BrowseDisplayMode
Button1.Text = "设置编辑模式为On"
End If
End Sub
 
至此,你可以开始运行你的第一个 Web Part 应用程序了。
 
四、 小结
 
很明显,本文仅是一个创建定制 Web Part 控件的入门篇。创建开发者定制的服务器端控件是 ASP.NET 2.0 提供的一项重要功能,如今借助于 Portal Framework ,我们又可以创建定制的 Web Part 控件,从而进一步扩展了这一功能。
 
实际上, ASP.NET Web Part 框架是一组极为丰富和复杂的技术。现在,既然你初步了解了 Web Part 的威力,那么接下来,你应该着手探索使用它进行一些更高级的开发—创建完整的、可个性化设置的 Web 应用程序(如本文前面图 2 所示的微软 Windows Live 门户网站)了。
 
【注】本文提供了示例程序完整的源码,读者可进行复制 / 粘贴试验(环境为 Windows XP Professiona l VS2005 )。






















本文转自朱先忠老师51CTO博客,原文链接:http://blog.51cto.com/zhuxianzhong/59820 ,如需转载请自行联系原作者