19.4 创建定制的Web Part
在给使用Portal Framework的页面添加项时,可以添加已有的ASP.NET Web服务器控件、用户控件或定制控件。除了这些项之外,还可以建立和合并定制的Web Part。使用WebParts类,可以创建自己的定制Web Part。尽管与ASP.NET定制服务器控件的开发类似,但创建定制的Web Part还要添加一些附加功能。创建一个继承于WebPart类(而不是继承于Control类)的类,可以使控件使用新的个性化特性,以及利用更强大的Portal Framework,使该控件可以关闭、最大化、最小化等。
要创建定制的Web Part控件,首先应在Visual Studio 2005中创建一个项目。在Visual Studio中,选择File | New Project,打开New Project对话框。在这个对话框中,选择Web Control Library。把项目命名为MyStateListBox,单击OK按钮创建该项目。该项目有一个类,其中包含一般ASP.NET服务器控件的基本架构。忽略这个架构,让该类创建一个定制的Web Part控件,而不是定制的ASP.NET服务器控件。程序清单19-14演示了创建定制Web Part控件的过程。
程序清单19-14 创建定制的Web Part控件
VB
Imports System
Imports System.Web
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Namespace Wrox
Public Class StateListBox
Inherits WebPart
Private _LabelStartText As String = " Enter State Name: "
Dim StateInput As New TextBox
Dim StateContents As New ListBox
Public Sub New()
Me.AllowClose = False
End Sub
<Personalizable(), WebBrowsable()> _
Public Property LabelStartText() As String
Get
Return _LabelStartText
End Get
Set(ByVal value As String)
_LabelStartText = value
End Set
End Property
Protected Overrides Sub CreateChildControls()
Controls.Clear()
Dim InstructionText As New Label
InstructionText.BackColor = Drawing.Color.LightGray
InstructionText.Font.Name = "Verdana"
InstructionText.Font.Size = 10
InstructionText.Font.Bold = True
InstructionText.Text = LabelStartText
Me.Controls.Add(InstructionText)
Dim LineBreak As New Literal
LineBreak.Text = "<br />"
Me.Controls.Add(LineBreak)
Me.Controls.Add(StateInput)
Dim InputButton As New Button
InputButton.Text = "Input State"
AddHandler InputButton.Click, AddressOf Me.Button1_Click
Me.Controls.Add(InputButton)
Dim Spacer As New Literal
Spacer.Text = "<p>"
Me.Controls.Add(Spacer)
Me.Controls.Add(StateContents)
ChildControlsCreated = True
End Sub
Public Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)
StateContents.Items.Add(StateInput.Text)
StateInput.Text = String.Empty
StateInput.Focus()
End Sub
End Class
End Namespace
C#
using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace Wrox
{
public class StateListBox : WebPart
{
private String _LabelStartText = " Enter State Name: ";
TextBox StateInput = new TextBox();
ListBox StateContents= new ListBox();
public StateListBox()
{
this.AllowClose = false;
}
[Personalizable(), WebBrowsable]
public String LabelStartText
{
get { return _LabelStartText; }
set { _LabelStartText = value; }
}
protected override void CreateChildControls()
{
Controls.Clear();
Label InstructionText = new Label();
InstructionText.BackColor = System.Drawing.Color.LightGray;
InstructionText.Font.Name = "Verdana";
InstructionText.Font.Size = 10;
InstructionText.Font.Bold = true;
InstructionText.Text = LabelStartText;
this.Controls.Add(InstructionText);
Literal LineBreak = new Literal();
LineBreak.Text = "<br />";
this.Controls.Add(LineBreak);
this.Controls.Add(StateInput);
Button InputButton = new Button();
InputButton.Text = "Input State";
InputButton.Click += new EventHandler(this.Button1_Click);
this.Controls.Add(InputButton);
Literal Spacer = new Literal();
Spacer.Text = "<p>";
this.Controls.Add(Spacer);
this.Controls.Add(StateContents);
ChildControlsCreated = true;
}
private void Button1_Click(object sender, EventArgs e)
{
StateContents.Items.Add(StateInput.Text);
StateInput.Text = String.Empty;
StateInput.Focus();
}
}
}
首先导入System.Web.UI.WebControls.WebParts命名空间。在创建这个定制控件时,一定要确保它继承于WebPart类,而不是Control类。如前所述,这会允许控件访问Portal Framework中一般定制控件不能访问的高级功能。
VB
Public Class StateListBox
Inherits WebPart
End Class
C#
public class StateListBox : WebPart
{
}
有了类结构后,定义几个属性,同时定义构造函数。构造函数直接使用WebPart类提供的一些功能。如果这个定制控件把Control类作为基类,使用WebPart.AllowClose属性,就不能使用这些功能。
VB
Public Sub New()
Me.AllowClose = False
End Sub
C#
public StateListBox()
{
this.AllowClose = false;
}
这个构造函数创建了一个控件,它把控件的AllowClose属性明确设置为False,表示Web Part在页面中生成时,没有与它关联的Close链接。由于使用WebPart类而不是Control类,所以该控件除了AllowClose属性之外,还有其他类属性,例如AllowEdit、AllowHide、AllowMinimize、AllowZoneChange等。
在程序清单19-14的例子中,有一个定制的属性LabelStartText。这个属性允许开发人员修改显示在控件顶部的指令文本。这个定制属性的一大区别是,它在Personalizable和WebBrowsable属性的前面。
Personalizable属性可以对属性进行个性化处理,而WebBrowsable属性指定属性是否应显示在Visual Studio的Properties窗口中。Personalizable属性可以使用PersonalizationScope枚举进一步定义。该枚举只有两个值Shared和User,可以用下面的方式定义:
VB
<Personalizable(PersonalizationScope.Shared), WebBrowsable()> _
Public Property LabelStartText() As String
Get
Return _LabelStartText
End Get
Set(ByVal value As String)
_LabelStartText = value
End Set
End Property
C#
[Personalizable(PersonalizationScope.Shared), WebBrowsable]
public String LabelStartText
{
get { return _LabelStartText; }
set { _LabelStartText = value; }
}
PersonalizationScope的User值表示针对每个用户所进行的修改。这是默认设置,表示如果用户对属性进行了修改,这些修改将只能由该用户看到,而其他浏览页面的用户看不到。如果PersonalizationScope设置为Shared,则一个用户进行的修改可以由请求页面的其他用户看到。
有了这些属性后,下一步是通过重写CreateChildControls方法,定义要在页面上显示什么内容。在程序清单19-14的例子中,CreateChildControls方法显示了Label、Literal、TextBox、Button和ListBox控件,除了定义这些控件的属性之外,还给按钮控件关联了一个事件(Button1_Click)。该事件也是在这个类中定义的。
有了定制的Web Part控件之后,就建立项目,从而创建DLL。接着打开要使用这个新控件的ASP.NET Web项目,从Visual studio工具箱中添加这个新控件。为此,右击工具箱中放置新控件的选项卡,选择Choose Items。单击Browse按钮,找到刚才创建的MyStateListBox.dll。之后,StateListBox控件会突出显示,并在Choose Toolbox Items对话框中处于选中状态,如图19-22所示。

图 19-22
单击OK按钮,把该控件添加到工具箱中。现在准备把这个新控件用作Web Part控件。为此,将该控件拖放到一个Web Part区域上。这会完成两个任务:首先使用Register指令在页面上注册该控件:
<%@ Register TagPrefix="cc1" Namespace="MyStateListBox.Wrox"
Assembly="MyStateListBox" %>
注册好后,这个控件就可以在页面上使用了。如果把它拖放到页面的设计界面上,就会得到如下结构的控件:
<cc1:StateListBox Runat="server" ID="StateListBox1"
LabelStartText=" Enter State Name: " AllowClose="False" />
在这个结构中有两个要点:第一,出现了定制属性LabelStartText,它使用默认值。第二,还包括AllowClose属性。出现AllowClose属性,只是因为前面让该控件继承于WebPart类,而不是Control。WebPart是被继承的类,所以可以访问这些WebPart专有的属性。把StateListBox控件绘制在页面上时,它实际上是更强大的Portal Framework的一部分,允许进行最小化和编辑。终端用户可以使用这个定制Web Part控件,就好像它是其他类型的Web Part控件一样,可以看出,创建自己的Web Part控件时将拥有很大的权限。
由于LabelStartText使用WebBrowsable属性,所以可以使用PropertyGridEditorPart控件,让终端用户直接在浏览器中编辑它。之后,如前面的程序清单19-5所示,终端用户在切换到Edit模式下后,就可以看到如图19-23所示的编辑功能。

图 19-23







