65.9K
CodeProject 正在变化。 阅读更多。
Home

自定义您的 Web Part Chrome

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.65/5 (10投票s)

2007 年 5 月 8 日

8分钟阅读

viewsIcon

79095

downloadIcon

690

这是一篇关于 ASP.Net 2.0 Web 部件主题的文章

Screenshot - image001.jpg

引言

Web 部件外框是 ASP.NET 2.0 Web 部件框架中的主要组件之一。它负责渲染包含在 Web 部件区域中的 Web 部件及其附属项,例如标题。然而,我们可以通过更改 WebPartZone 类的某些属性值来在很大程度上自定义 Web 部件外框渲染 Web 部件的方式。有时我们仍然需要修改 Web 部件外框渲染 Web 部件的方式以满足某些特定需求。本文就是关于这种修改的。

先决条件

要理解本文,您需要熟悉 ASP.NET Web 部件框架。如果您对此不熟悉,我建议您阅读 Darren Neimke 撰写的、由 Manning Publications 出版的《ASP.Net 2.0 Web Parts in Action》。这本书将为您提供有关它的良好理解。

背景

前几天,当我试图向同事展示 Web 部件是什么时,我打开了 iGoogle 页面。我的同事提到他喜欢 Google 设计标题栏的方式,只放置了三个图片按钮:一个用于关闭,一个用于最小化或恢复,另一个用于下拉菜单。然后他问我是否可以在 .NET 中做到这一点。我没有仔细思考,就坚定地回答:“当然!你以为你在跟谁说话?” 但在那之后,我开始觉得我应该三思而后言。

无论如何,话已至此,如果我必须食言,我将感到尴尬,所以我花了几天时间思考,以下是我取得的成果。

CustomisedWebPartZone 类

现在,我们开始吧。Web 部件外框由 Web 部件区域创建和使用,用于渲染 Web 部件。在 WebPartZone 类中,有一个可重写的函数名为 CreateWebPartChrome。首先,我们将编写一个名为 CustomisedWebPartZone 的类,它继承自这个类,并重写该函数以返回我们将要编写的 CustomisedWebPartChrome。该函数代码如下。

Protected Overrides Function CreateWebPartChrome() As 
    System.Web.UI.WebControls.WebParts.WebPartChrome
    Return New CustomisedWebPartChrome(Me, 
        WebPartManager.GetCurrentWebPartManager(Me.Page))
End Function

WebPartZone 类还有一个受保护的属性,我们的 CustomisedWebPartChrome 类稍后需要调用它,所以我们必须创建一个友元(程序集)属性将其暴露给其他类。

Protected Friend Shadows ReadOnly Property RenderClientScript() As Boolean
    Get
        Return MyBase.RenderClientScript
    End Get
End Property

CustomisedWebPartChrome 类

现在,我们将创建 CustomisedWebPartChrome 类,它继承自 WebPartChrome 类。我们将转换并覆盖原始的 Zone 属性,该属性返回 WebPartZoneBase,而是返回我们的 CustomisedWebPartZone

Protected Shadows ReadOnly Property Zone() As CustomisedWebPartZone
    Get
        Return MyBase.Zone
    End Get
End Property

WebPartChrome 类的核心方法是 RenderWebPart 方法。正是这个方法渲染了整个外框(应该包含一个 Web 部件),如果我们编写代码让它写入“Hello World”,那么无论渲染哪个 Web 部件,最终都会在 Web 部件区域中写入“Hello World”。在这种情况下,我们将让它渲染一个顶部的标题栏,然后是 Web 部件内容。将使用一个 Table 元素作为框架,如下面的简单 HTML 代码所示。

<Table>
    <TR>
        <TD>
            <!—Title Bar Goes Here -->
        </TD>
    </TR>
    <TR>
        <TD>
            <!—Web Part Contents Go Here -->
        </TD>
    </TR>
<Table>

现在,我们将重写这个 RenderWebPart 方法。我将解释一些代码片段,您可以参考附件源代码中的其余部分。

If Me.Zone.RenderClientScript Then
    writer.AddAttribute(HtmlTextWriterAttribute.Id, 
        Me.GetWebPartChromeClientID(webPart))
End If

这部分将外框的 ID 应用于外框的 table 元素,这是覆盖整个外框的元素。在运行时,会有一些 JavaScript 被自动写入,以使外框能够拖放到另一个区域。

RenderTitleBar(writer, webPart)

这行代码调用了我们将要编写的另一个方法。该方法负责渲染外框的标题栏区域,这也是我们想要自定义的部分。我们将在下一节回到这个方法。

If webPart.ChromeState = PartChromeState.Minimized Then 
    writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none")
End If

这段代码告诉浏览器在最小化外框时隐藏 Web 部件内容部分。

RenderPartContents(writer, webPart)

这行代码渲染了 Web 部件的内容。

RenderTitleBar 方法

如前所述,我们回到 RenderTitleBar 方法。此方法用于渲染 HTML 代码中所示的标题栏。我希望此外框无论外框样式如何都渲染标题栏。但是,如果您只想在外框样式为“TitleOnly”或“TitleAndBorder”时渲染标题栏,可以将该条件放入此方法中。同样,我将在文章中解释足够的代码供理解,您可以在附件源代码中查找其余代码。

writer.AddAttribute(HtmlTextWriterAttribute.Id, 
    Me.GetWebPartTitleClientID(webPart))

这行代码将标题栏的 ID 应用于 TD 元素,以指示它是 Web 部件外框的标题栏。这对拖放功能很重要。

RenderButton(writer, clientID, "verbs", webPart)

此方法用于渲染标题栏上的一个按钮。我将在下一节进行解释。需要渲染三个按钮:Verbs、Minimize/Restore 和 Close。

现在,标题栏已基本完成。我们唯一需要添加的是包含您可能添加到 Web 部件中的其他动词的弹出菜单。您可以选择自己编写一些 JavaScript 代码来实现这一点。然而,ASP.NET 提供了一个方便的 JavaScript 类,专门用于这种情况,那就是 WebPartMenu。我们所要做的就是创建它,并将正确的参数传递给它的构造函数,仅此而已。如果您查看 RenderTitleBar 方法中的最后一个代码块,您会找到一段注册客户端脚本的代码来实现这一点。该类的构造函数如下。

new WebPartMenu(<Button Wrapper Object>, <Button Object>, 
    <Pop-up Menu Object>)

如果您向上滚动一点,您会找到创建弹出菜单的代码块。请注意,我给它提供了外框客户端 ID 加上后缀“verbsMenu”。此 ID 然后在客户端脚本中用于查找弹出菜单元素。另一个方法 RenderVerb 也被调用以将动词渲染到弹出菜单中。我将在下一节之后的一节中介绍它。

RenderButton 方法

让我们来探索一下 RenderButton 方法。我们的按钮将是一个 HTML 图像元素,用一个 span 元素包裹。span 元素具有 ID 属性,设置为外框客户端 ID 后跟按钮名称。此 ID 对于 Verbs 按钮至关重要,因为它用于在客户端 WebPartMenu 类的构造函数中标识按钮。继续阅读代码,您会发现以下代码片段。

If buttonName = "verbs" Then
    img.Attributes.Add("id", String.Format("{0}VerbsPopup", 
        clientID))
Else
    img.Attributes.Add("onclick",
        String.Format("__wpm.SubmitPage('{0}', 
        '{2}:{1}');", Zone.ClientID.Replace("_"c, 
        "$"c), webPart.ID, buttonName))
End If

对于 Verbs 按钮,我们需要在图像元素中添加另一个 ID,它充当按钮。对于 Minimize、Restore 和 Close 按钮,我们需要添加一段 JavaScript 代码来处理 onclick 事件。这段代码调用 __wpm 对象,这是一个代表 Web 部件管理器(Web Part Manager)的客户端对象。该对象有一个名为 SubmitPage 的方法,其签名如下。

SubmitPage(<WebPartZoneRepresentationString>,<Command>)

第一个参数只是 Web 部件区域的客户端 ID,其中“_”被“$”替换。第二个参数是 Web 部件的 ID,后跟“:”,然后是命令名称,即 close、minimize 或 restore。

RenderVerb 方法

此方法在前面解释的 RenderTitleBar 方法中被调用。我们添加了一些 JavaScript 代码来处理锚定元素(anchor element)的 onclick 事件。如前所述,调用客户端 __wpm 对象的 SubmitPage 方法。请注意,这次我只是使用区域 ID 作为第一个参数,而不是像之前那样使用修改后的客户端 ID。微软就是这样处理动词的。我个人认为,如果您在 RenderButton 方法中这样做,也会起作用,但我还没有尝试过。

第二个参数是单词“partverb”,后跟“:”,然后是动词的 ID,然后是“:”和 Web 部件的 ID。这足以让 ASP.NET 调用动词的服务器端事件处理程序。

现在是时候测试了

为了测试我们自定义的 Web 部件外框,我们将使用一个名为 MyWebPart 的用户控件来创建一个 Web 部件。该用户控件将实现 IWebPart,以便我们能够添加描述、标题等。它还将实现 IWebActionable,以便我们能够添加自定义动词。

我们将添加的两个自定义动词是 SayHelloWorldSayMyWebPart,它们将分别显示文本“Hello World”和“My Web Part”。SayHelloWorld 还将附加一个图像,以测试动词图像的渲染。

default.aspx 文件中,要使用我们自定义的 Web 部件区域和外框,我们必须添加以下指令来注册一个标签前缀。

<%@ Register Namespace="CustomisedControls" TagPrefix="cc" %>

之后,我们就可以像使用普通 WebPartZone 一样使用 CustomisedWebPartZone。尝试将 MyWebPart 的实例在两个区域之间拖放,看看区别。您还可以使用编辑器区域编辑 Web 部件的某些属性,看看它是如何渲染的。

总结

本文连同源代码,向您展示了一种自定义 Web 部件外框的方法。从中,我相信您将能够用它来做更多花哨的事情。只有您的想象力是限制。

历史

2007 年 5 月 6 日 – 提交原文 + 源代码。

© . All rights reserved.