DeclarativeCatalogPart 控件使您能够将 WebPart 的目录或其他服务器控件添加到网页。这可让用户在运行时更改页面上可用的控件集和功能。目录是 WebPart 或其他服务器控件的列表,当页面处于目录显示模式时,该列表是可见的。在设计时,您可以将控件添加到 DeclarativeCatalogPart 控件中;在运行时,用户可以选择要在页面中查看的控件,方法是从目录列表中进行选择。
当用户在运行时从控件目录中选择控件时,DeclarativeCatalogPart 控件会将控件的新实例添加到网页中。用户可以将目录中同一控件的多个实例添加到网页中。
启用 DeclarativeCatalogPart Web 服务器控件
必须将 DeclarativeCatalogPart 控件放在 CatalogZoneBase 区域(如 CatalogZone 区域)中。仅当网页处于目录显示模式时 DeclarativeCatalogPart 控件才变为可见。
创建控件的应用程序范围的目录
DeclarativeCatalogPart 控件使您能够设置站点中可用的控件目录。您可以将 WebPartsListUserControlPath 属性设置为用户控件(包含目录中的服务器控件列表)的路径,而不是在 DeclarativeCatalogPart 控件中声明单个服务器控件。在运行时,用户控件中引用的服务器控件会加载到目录中。此策略使多个页面或站点能够引用相同的用户控件来创建目录。当更新用户控件中的服务器控件列表时,基于该用户控件的所有目录将被更新。
一、DeclarativeCatalogPart 类
使开发人员能够将 WebPart 或其他服务器控件的目录以声明性、页持久性格式添加到网页上。无法继承此类。
正如 Web 部件控件集中有面向工具的区域一样,其中也有面向工具的 Part 控件,并且这些控件中的每一个都必须位于某种类型的工具区域中。Web 部件控件集中面向工具的部件控件具有两个显著特征:
·它们是帮助器控件,最终用户可用来个性化 Web 部件页上的控件。
·它们只在某些显示模式下可见。
DeclarativeCatalogPart 是必须位于 CatalogZoneBase 类型的区域(如随 Web 部件控件集提供的 CatalogZone 区域)中的部件控件。仅当网页处于目录显示模式时 DeclarativeCatalogPart 控件才变为可见。
DeclarativeCatalogPart 控件为开发人员提供了一种以声明方式向网页上的目录添加一组服务器控件的方法。Web 部件控件集中的目录只是在页面处于目录显示模式时可见的 WebPart 或其他服务器控件的一个列表。用户可以从列表中选择控件并将它们添加到网页中,这有效地为用户提供了改变页面上的控件集和功能的能力。
说明: 用户可以向网页的目录中添加同一控件的多个实例。
使用 DeclarativeCatalogPart 控件创建服务器控件的目录的一个优点是它不需要任何编码。网页开发人员可以完全以声明性(或页持久性)格式使用该控件,因此也可以这样使用该控件的名称。
DeclarativeCatalogPart 控件具有一个有用的属性,它允许开发人员建立可在整个站点中使用的控件目录。开发人员可以将 WebPartsListUserControlPath 属性值设置为用户控件(包含应在目录中的服务器控件列表)的路径,而不是在 DeclarativeCatalogPart 控件中声明单独的服务器控件。在运行时,用户控件中引用的服务器控件在目录中加载。这样,多个页面或站点可以引用相同的用户控件来创建目录。当该用户控件的服务器控件列表更新时,将更新基于该用户控件的所有目录。
DeclarativeCatalogPart 类具有许多重写继承属性的公共属性。这些属性 (Property) 中的大多数实际上并不用于呈现该控件;重写它们仅仅是为了可以对它们设置特殊的代码属性 (Attribute) 以在设计工具(如 Microsoft Visual Studio 2005)中隐藏它们。不应使用这些隐藏的属性,因为它们对呈现不起任何作用。在 Visual Studio 的 IntelliSense 和“属性”窗格中隐藏这些属性,可帮助开发人员避免错误使用它们。所有这些隐藏的属性在其各自的“帮助”主题中都进行了此类说明。
DeclarativeCatalogPart 类还具有几个方法。GetAvailableWebPartDescriptions 方法检索目录中每个 WebPart 控件的 WebPartDescription 对象,这使得 DeclarativeCatalogPart 控件无需创建每个服务器控件的实例即可显示其有关信息。另一个方法是 GetWebPart 方法。此方法根据传入的说明,获取特定 WebPart 控件的实例。
说明: 为改进可访问性,在 元素中呈现了 DeclarativeCatalogPart 控件。元素在 DeclarativeCatalogPart 控件中对一组用于编辑的相关控件进行分组,还为在那些兼用于可视化用户代理(如普通 Web 浏览器)和面向语音的用户代理(如屏幕阅读软件)的控件之间进行选项卡式导航提供便利。
1.1、示例
下面的代码示例演示如何在网页上以声明方式使用 DeclarativeCatalogPart 控件。此示例包含四部分:
·一个用户控件,可用于更改 Web 部件页上的显示模式。
·一个网页,包含一个 CatalogZone 控件和一个 DeclarativeCatalogPart 控件。
·一个包含两个自定义 WebPart 控件的源代码文件。
·对您在浏览器中加载页面时示例的运行方式的说明。
此代码示例的第一部分是用户控件,可用于更改页的显示模式。
<%@ control language="C#" classname="DisplayModeMenuCS"%>
// Use a field to reference the current WebPartManager.
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 dropdown 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 is allowed, toggle the scope.
protected void RadioButton2_CheckedChanged(object sender, EventArgs e)
{
if (_manager.Personalization.CanEnterSharedScope &&
_manager.Personalization.Scope == PersonalizationScope.User)
_manager.Personalization.ToggleScope();
}
Borderwidth="1" Width="230" BackColor="lightgray" Font-Names="Verdana, Arial, Sans Serif" > Text=" Display Mode" Font-Bold="true" Font-Size="8" Width="120" AssociatedControlID="DisplayModeDropdown"/> AutoPostBack="true" Width="120" OnSelectedIndexChanged="DisplayModeDropdown_SelectedIndexChanged" /> Text="Reset User State" ToolTip="Reset the current user's personalization data for the page." Font-Size="8" OnClick="LinkButton1_Click" /> GroupingText="Personalization Scope" Font-Bold="true" Font-Size="8" Visible="false" > Text="User" AutoPostBack="true" GroupName="Scope" OnCheckedChanged="RadioButton1_CheckedChanged" /> Text="Shared" AutoPostBack="true" GroupName="Scope" OnCheckedChanged="RadioButton2_CheckedChanged" />
该代码示例的第二部分为网页。在页顶部有两条 Register 指令,一条针对用户控件,一条针对包含两个自定义 WebPart 控件的已编译组件。注意,该页有一个对 DeclarativeCatalogPart 控件的声明性引用,该控件嵌套在声明性元素的适当层次结构内,如本主题“备注”部分所述。
<%@ page language="c#" %>
<%@ register TagPrefix="uc1"
TagName="DisplayModeMenuCS"
Src="DisplayModeMenuCS.ascx" %>
<%@ register tagprefix="aspSample"
Namespace="Samples.AspNet.CS.Controls"
Assembly="UserInfoWebPartCS" %>
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
>
DeclarativeCatalogPart Control
Font-Names="Verdana, Arial"
Font-Size="110%"
BackColor="LightBlue" />
Runat="server"
DisplayMode="HyperLink"
Title="Favorites">
MSDN
ASP.NET
MSN
runat="server"
Title="Web Parts Catalog"
ChromeType="TitleOnly"
Description="Contains a user control with Web Parts and
an ASP.NET Calendar control.">
Title="My Calendar"
Description="ASP.NET Calendar control used as a personal calendar." />
runat="server"
id="userinfo1"
title = "User Information WebPart"
Description ="Contains custom, editable user information
for display on a page." />
runat="server"
id="TextDisplayWebPart1"
title = "Text Display WebPart"
Description="Contains a label that users can dynamically update." />
此代码示例的第三部分是两个 WebPart 控件的源代码。注意,这些控件的一些属性 (Property) 用 WebBrowsable 属性 (Attribute) 标记。这使得 PropertyGridEditorPart 控件能够动态地生成用户界面 (UI),以便用户在这些控件处于编辑模式时编辑这些属性。这些属性 (Property) 也用 WebDisplayName 属性 (Attribute) 标记,指定在编辑用户界面中的每个控件旁显示的标签文本。
必须编译此源代码,代码示例才能运行。可以显式编译源代码,并将结果程序集放在网站的 Bin 文件夹或全局程序集缓存中。另外,也可将源代码放入站点的 App_Code 文件夹中,源代码将在运行时在此文件夹中进行动态编译。
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
namespace Samples.AspNet.CS.Controls
{
[AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
public class UserInfoWebPart : WebPart
{
HttpServerUtility server = HttpContext.Current.Server;
private String _userNickName = "Add a nickname.";
private String _userPetName = "Add a pet's name.";
private DateTime _userSpecialDate = DateTime.Now;
private Boolean _userIsCurrent = true;
private JobTypeName _userJobType = JobTypeName.Unselected;
public enum JobTypeName
{
Unselected = 0,
Support = 1,
Service = 2,
Professional = 3,
Technical = 4,
Manager = 5,
Executive = 6
}
Label NickNameLabel;
Label PetNameLabel;
Label SpecialDateLabel;
CheckBox IsCurrentCheckBox;
Label JobTypeLabel;
// Add the Personalizable and WebBrowsable attributes to the
// public properties, so that users can save property values
// and edit them with a PropertyGridEditorPart control.
[Personalizable(), WebBrowsable, WebDisplayName("Nickname")]
public String NickName
{
get
{
object o = ViewState["NickName"];
if (o != null)
return (string)o;
else
return _userNickName;
}
set { _userNickName = server.HtmlEncode(value); }
}
[Personalizable(), WebBrowsable, WebDisplayName("Pet Name")]
public String PetName
{
get
{
object o = ViewState["PetName"];
if (o != null)
return (string)o;
else
return _userPetName;
}
set { _userPetName = server.HtmlEncode(value); }
}
[Personalizable(), WebBrowsable(), WebDisplayName("Special Day")]
public DateTime SpecialDay
{
get
{
object o = ViewState["SpecialDay"];
if (o != null)
return (DateTime)o;
else
return _userSpecialDate;
}
set { _userSpecialDate = value; }
}
[Personalizable(), WebBrowsable(), WebDisplayName("Job Type")]
public JobTypeName UserJobType
{
get
{
object o = ViewState["UserJobType"];
if (o != null)
return (JobTypeName)o;
else
return _userJobType;
}
set { _userJobType = (JobTypeName)value; }
}
[Personalizable(), WebBrowsable(), WebDisplayName("Is Current")]
public Boolean IsCurrent
{
get
{
object o = ViewState["IsCurrent"];
if (o != null)
return (Boolean)o;
else
return _userIsCurrent;
}
set { _userIsCurrent = value; }
}
protected override void CreateChildControls()
{
Controls.Clear();
NickNameLabel = new Label();
NickNameLabel.Text = this.NickName;
SetControlAttributes(NickNameLabel);
PetNameLabel = new Label();
PetNameLabel.Text = this.PetName;
SetControlAttributes(PetNameLabel);
SpecialDateLabel = new Label();
SpecialDateLabel.Text = this.SpecialDay.ToShortDateString();
SetControlAttributes(SpecialDateLabel);
IsCurrentCheckBox = new CheckBox();
IsCurrentCheckBox.Checked = this.IsCurrent;
SetControlAttributes(IsCurrentCheckBox);
JobTypeLabel = new Label();
JobTypeLabel.Text = this.UserJobType.ToString();
SetControlAttributes(JobTypeLabel);
ChildControlsCreated = true;
}
private void SetControlAttributes(WebControl ctl)
{
ctl.BackColor = Color.White;
ctl.BorderWidth = 1;
ctl.Width = 200;
this.Controls.Add(ctl);
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("Nickname:");
writer.WriteBreak();
NickNameLabel.RenderControl(writer);
writer.WriteBreak();
writer.Write("Pet Name:");
writer.WriteBreak();
PetNameLabel.RenderControl(writer);
writer.WriteBreak();
writer.Write("Special Date:");
writer.WriteBreak();
SpecialDateLabel.RenderControl(writer);
writer.WriteBreak();
writer.Write("Job Type:");
writer.WriteBreak();
JobTypeLabel.RenderControl(writer);
writer.WriteBreak();
writer.Write("Current:");
writer.WriteBreak();
IsCurrentCheckBox.RenderControl(writer);
}
}
[AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
public class TextDisplayWebPart : WebPart
{
private String _contentText = null;
TextBox input;
Label DisplayContent;
Literal lineBreak;
[Personalizable(), WebBrowsable]
public String ContentText
{
get { return _contentText; }
set { _contentText = value; }
}
protected override void CreateChildControls()
{
Controls.Clear();
DisplayContent = new Label();
DisplayContent.BackColor = Color.LightBlue;
DisplayContent.Text = this.ContentText;
this.Controls.Add(DisplayContent);
lineBreak = new Literal();
lineBreak.Text = @"
";
Controls.Add(lineBreak);
input = new TextBox();
this.Controls.Add(input);
Button update = new Button();
update.Text = "Set Label Content";
update.Click += new EventHandler(this.submit_Click);
this.Controls.Add(update);
}
private void submit_Click(object sender, EventArgs e)
{
// Update the label string.
if (input.Text != String.Empty)
{
_contentText = input.Text + @"
";
input.Text = String.Empty;
DisplayContent.Text = this.ContentText;
}
}
}
}
当在浏览器中加载页时,请在“显示模式”下拉列表控件中选择“目录模式”以切换到目录模式。在目录模式下,可看到可供添加到页中的控件。添加所有三个控件,然后使用“显示模式”下拉列表将该页面返回到浏览模式。这三个控件显示在该页面上。如果使用“显示模式”下拉列表并将该页面切换到编辑模式,则可以单击“用户信息 Web 部件”控件标题栏中的谓词菜单(向下箭头),然后单击“编辑”编辑该控件。当该编辑用户界面可见时,可看到 PropertyGridEditorPart 控件。注意,将为以 WebBrowsable 属性 (Attribute) 标记的 UserInfoWebPart 类的每个属性 (Property) 呈现一个控件。如果在编辑用户界面进行一些更改并单击“应用”按钮,可使用“显示模式”下拉列表使页返回到浏览模式,然后查看编辑更改的完整效果。