带有集合属性和嵌入式资源的XP样式导航栏服务器控件

分享于 

14分钟阅读

Web开发

  繁體

索引

简介

本文介绍如何创建具有 collection 属性并使用嵌入式网络资源的ASP.NET 服务器控件。 这样,我们将创建一个XP外观导航服务器控件。 本文将重点介绍:

  • 如何使用 collection 属性创建服务器控件
  • collection 属性的设计器中显示 collection 编辑器
  • 实现网络资源概念
Navigation bar rendered in internet explorer

为什么本文?

我为什么要写这个控件? 使用属性创建服务器控件并非易事。 但是创建具有 collection <code> 属性的控件需要几个步骤。 我还没有找到任何可以管理 collection 属性和设计时间支持的好例子。 本文主要讨论如何创建 collection 类并从 Visual Studio 设计器的collection 编辑器中添加 collection

自定义服务器控件应该总是像其他 ASP.NET 控件一样易于使用。 许多自定义控件使用javascript和图像,并指示用户将这些内容复制到服务器上的某个位置,以使控件正常工作。 在本文中,我将解释如何通过在程序集中嵌入资源来避免这一。

ASP.NET 服务器控件简介

本文并不是一步一步地说明如何创建服务器控件。 这是由几个作家写的。 在阅读本文之前,如果不了解 ASP.NET 自定义服务器控件,请参阅本文,在继续阅读本文之前,我将参考本文。

ASP.NET 允许开发自定义的可以重用控件。 这些控件是从 System.Web.UI.WebControl 继承的。 创建新的控件库项目时,WebControl 类中的Render() 方法将被重写。 ASP.NET 处理页面中的每个控件,并要求它们通过调用 Render()的方法来呈现。 Render() 方法接受 HTMLTextWriter 对象并将呈现的HTML写入响应。 在本例中,我还重写了 OnInit() 方法以启动启动客户端脚本。

类关系图

Class diagram for Navigation bar control

NavigationBar成员

姓名描述
Public methodCollapsed指示控件是否必须折叠或者展开
Public methodHeaderCssClassheader 文本的样式表类 NAME
Public methodHeaderFontheader 文本的字体 NAME
public 方法HeaderFontSize指定 header 字体大小
public 方法HeaderForeColor指定 header 文本的颜色
public 方法HeaderText菜单 header 文本默认情况下,这是"标题 Header"
public 方法ItemsNavigationBarItem 对象集合
public 方法ItemsBgColor项单元格的背景色
public 方法ItemsCssClass项目的样式表类
public 方法ItemsFont导航栏项目的字体 NAME
public 方法ItemsFontSize导航栏项目的字体大小
public 方法MenuItemSpace每个菜单项之间的间距
public 方法PanelColor菜单容器的颜色。 默认情况下,这是XP蓝色
public 方法SpacerWidth左图像和菜单项文本之间的宽度

NavigationBarItems Collection 类

collection 类包含类似类型的对象,这些对象可以使用索引访问。 .NET 允许不同的方法创建 collection 类。 NavigationBarItemsCollection 类包含 NavigationBarItem 对象。 这里 collection 类实现 ICollectionIList 接口,这些接口强制类实现 collection 功能。 对象保持 inside 为 ArrayList。 下面的代码Fragment显示了这个 collection 类中使用的公共函数。

publicint Add(NavigationBarItem item)
{
 returnthis._Items.Add(item);
}publicvoid Clear()
{
 this._Items.Clear();
}publicvoid RemoveAt(int index)
{
 this._Items.RemoveAt(index);
}publicint Count
{
 get {
 returnthis._Items.Count;
 }
}

要使 collection 成员通过索引进行访问,使用以下属性:

public NavigationBarItem this[int index]
{
 get {
 return (NavigationBarItem)this._Items[index];
 }
 set {
 this._Items[index] = (NavigationBarItem)value;
 }
}

这样,程序员就可以从 collection 访问 NavigationBarItem 对象,如下所示:

NavigationBarItem item = NavigationBar1.Items[1];

将 Collection 类设置为属性

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Editor(typeof(System.ComponentModel.Design.CollectionEditor),
typeof(System.Drawing.Design.UITypeEditor)),
PersistenceMode(PersistenceMode.InnerDefaultProperty), MergableProperty(false)]public NavigationBarItemsCollection Items
{
 get { return _Items; }
}

简单地将 collection 类设置为属性在VSDesigner中不能正常工作。 它将在通过 Collection 编辑器添加一个新条目时显示 System.Object。 但是使用代码可以添加。

要通过设计视图添加项目,需要指定 below 属性:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Editor(typeof(System.ComponentModel.Design.CollectionEditor),
typeof(System.Drawing.Design.UITypeEditor)),
PersistenceMode(PersistenceMode.InnerDefaultProperty), MergableProperty(false)]

DesignerSerializationVisibilityAttribute 用于在设计时序列化属性。 有关该属性的更多信息,请查看 MSDN文档列表。PersistenceMode 是另一个属性,它说明了属性应该如何在页面上。 PersistenceMode.InnerDefaultProperty 通知 ASP.NET 将项作为内部标记保存。

要设置这里属性,需要继承 ControlDesigner的类。 ControlDesigner 是帮助扩展网页控件设计时间行为的基类。 NavigationBarDesigner 是从 ControlDesigner 派生的类。 下面的代码Fragment显示重写的Initialize() 方法。

publicoverridevoid Initialize(System.ComponentModel.IComponent component)
{
 base.Initialize (component);
 this._NavigationBar = (NavigationBar)component;
}

NavigationBarItemBuilder类

此类是从 ControlBuilder 类派生的。 大多数 ASP.NET 中的控件都将与 ControlBuilder 类关联,这有助于解析控件及其内部标记。 NavigationBarItemBuilder 重写 AllowWhitespaceLiterals()HtmlDecodeLiterals() 之类的方法。 AllowWhitespaceLiterals() 解析控件内容内容中的空白,因为返回了 true 值。 这里方法总是返回 true 值。 因此,该功能被重写以返回 false 值。 重写 HtmlDecodeLiterals() 以解码标记内容上的HTML字符。 检查以下代码段:

publicoverridebool AllowWhitespaceLiterals()
{
 returnfalse;
}publicoverridebool HtmlDecodeLiterals()
{
 returntrue;
}

嵌入资源

我已经看到许多带有使用指南的自定义控件,如:

  • 将图像复制到服务器上的映像文件夹
  • 将 js文件复制到包括服务器上的目录。

使用控件嵌入资源是一个帮助创建各种服务器控件的概念,而不需要这些先决条件。

控制使用指南的问题

在 ASP.NET 1.1中,类似样式表,JavaScript文件部署在一个包中,并在客户机中安装在不正确的位置。

web服务的WebResource概念克服了所有这些问题,因此所有这些外部资源都可以在程序集中嵌入并在运行时加载。 在运行带有 NavigationBar 控件的页面时,可以从页代码源中看到对 WebResource.axd的引用,这可以处理这些嵌入的资源。 querystring 变量表示时间戳值和请求的资源 NAME。 若要嵌入文件,请将文件的生成操作设置为"嵌入式资源"。 下面的图片说明了网络资源是如何工作的。

WebResource architecture

从嵌入资源中检索

EmbeddedResourceManager 是一个管理所有嵌入资源的类。 以下代码段显示如何从嵌入资源检索 header 映像。

publicstring HeaderBackground
{
 get {
 string BgUrl = _NavigationBar.Page.ClientScript.GetWebResourceUrl
 (_NavigationBar.GetType(), 
 "System.Web.UI.WebControls.headerbg.gif");
 return BgUrl;
 }
}

Page.ClientScript.GetWebResourceUrl 用于获取嵌入的资源 URL。 GetWebResourceUrl() 返回资源的临时 URL。

查找 AssemblyInfo.cs

本节介绍如何在 AssemblyInfo.cs 文件中添加嵌入的资源详细信息。

[assembly: TagPrefix("System.Web.UI.WebControls", "W3Hearts")]

上面 语句用于设置控件的tagprefix。 下面是 tagprefix的示例。

<W3Hearts:NavigationBarid=NavigationBar1 runat="server"></W3Hearts:NavigationBar>

页面级别标记前缀可以由用户修改。 添加自定义控件时,Visual Studio 编辑器在页头中生成类似的标记。

<%@RegisterAssembly="NavigationBar"Namespace="System.Web.UI.WebControls"TagPrefix="W3Hearts"%>

下面的代码用于嵌入资源:

[assembly: System.Web.UI.WebResource
 ("System.Web.UI.WebControls.NavigationBar.js","text/js", PerformSubstitution = true)][assembly: System.Web.UI.WebResource
 ("System.Web.UI.WebControls.headerbg.gif", "image/gif")]
[assembly: System.Web.UI.WebResource
 ("System.Web.UI.WebControls.downarrow.gif", "image/gif")]
[assembly: System.Web.UI.WebResource
 ("System.Web.UI.WebControls.left1.gif", "image/gif")]
[assembly: System.Web.UI.WebResource
 ("System.Web.UI.WebControls.spacer.gif", "image/gif")]
[assembly: System.Web.UI.WebResource
 ("System.Web.UI.WebControls.uparrow.gif", "image/gif")]

这指定了资源 NAME 及其类型。 资源 NAME 应该从默认名称空间开始。 这里方法在嵌入资源位于子文件夹时失败。

用于展开/折叠菜单的

这个控件对JavaScript函数使用 NavigationBar.js 文件,其中包含用于扩展/collapse 导航栏的函数。 控件右边的顶部和底部箭头从嵌入的资源中加载。 以下示例显示如何在JavaScript函数中检索嵌入的资源 URL:

function Toggle(obj,NavigationBarId)
{
 if(document.getElementById(obj).style.display == 'none')
 {
 document.getElementById(obj).style.display = 'block';
 document.getElementById(NavigationBarId + "_Arrow").src =
 '';
 }
 else {
 document.getElementById(obj).style.display = 'none';
 document.getElementById(NavigationBarId + "_Arrow").src =
 '';
 }
}

这里控件的已知问题

  • NavigationBarItemsViewState 管理问题
  • 直接从 Datasource 中缺少绑定数据

结论

在本文中,我们使用 Collection 属性和嵌入式资源来创建定制服务器控件。 Collection 属性包含可以从设计视图中添加的NavigationBarItem 对象的Collection。

WebResource 是 ASP.NET 2.0的一个新概念,它帮助开发人员在不单独部署资源文件的情况下使用这些控件。


Server  控制  COL  Collect  style  collection  
相关文章