jQuery 是一个非常精简强大的 JavaScript 函式库,最近看到一个消息,未来微软的 ASP.NET 也会全面支持 jQuery,详见「 微软将在 ASP.NET 相关产品中全面支持 jQuery」一文。笔者在之前就被 jQuery 简短有力的程序语法所吸引,也把 jQuery 套用在服务器控件中,在本文将示范如何将 jQuery 的 ContextMenu plugin 封装成服务器控件,使开发人员在使用上更为简便。

程序代码下载:ASP.NET Server Control - Day30.rar

 

一、jQuery ContextMenu plugin

ContextMenu plugin 是基于 jQuery 开发的右键选单插件,它只需要非常简短的程序代码,就可以建立出相当美观的右键选单,详细说明请参阅以下网址。

http://www.trendskitchens.co.nz/jquery/contextmenu/

 

image

以上图右键选单为例,我们看一下它的 HTML 原始码及 JavaScript 程序代码。

HTML 原始码

    <div class="contextMenu" id="myMenu1">
      <ul>
        <li id="open"><img src="folder.png" /> Open</li>
        <li id="email"><img src="email.png" /> Email</li>
        <li id="save"><img src="disk.png" /> Save</li>
        <li id="close"><img src="cross.png" /> Close</li>
      </ul>
    </div>

 

 

 

JavaScript 程序代码

   $('span.demo1').contextMenu('myMenu1', {
 
      bindings: {
 
        'open': function(t) {
          alert('Trigger was '+t.id+'\nAction was Open');
        },
 
        'email': function(t) {
          alert('Trigger was '+t.id+'\nAction was Email');
        },
 
        'save': function(t) {
          alert('Trigger was '+t.id+'\nAction was Save');
        },
 
        'delete': function(t) {
          alert('Trigger was '+t.id+'\nAction was Delete');
        }
      }
    });

 

 

 

二、实作 ContextMenu 控件

接下来我们将开始实作,把 ContextMenu plugin 封装为服务器控件,想辨法输出所需的 HTML 原始码及 JavaScript 程序代码。

step1. 定义选单项目集合类别

我们定义 TBMenuItem 类别来描述选单项目,TBMenuItemCollection 类别为选单项目集合。服务器控件会依这个选单项目的集合类别,来输出 HTML 码中 <ul> Tag 的内容。


image

 

step2. 实作 TBContextMenu 控件

继承 WebControl 命名为 TBContextMenu,因为这个控件是没有 UI,所以自订控件 Designer 来呈现设计阶段的控件外观。

    ''' <summary>
    ''' 右選選單控制項。
    ''' </summary>
    < _
    Description("右選選單控制項"), _
    Designer(GetType(TBContextMenuDesigner)), _
    ToolboxData("<{0}:TBContextMenu runat=server></{0}:TBContextMenu>") _
    > _
    Public Class TBContextMenu
        Inherits WebControl
 
    End

 

 

 

 

TBContextMenuDesigner 只是单纯显示设计阶段的控件外观。

    ''' <summary>
    ''' 擴充 TBContextMenu 控制項的設計模式行為。
    ''' </summary>
    Public Class TBContextMenuDesigner
        Inherits System.Web.UI.Design.ControlDesigner
 
        ''' <summary>
        ''' 用來在設計階段表示控制項的 HTML 標記。
        ''' </summary>
        Public Overrides Function GetDesignTimeHtml() As String
            Dim sHTML As String
 
            sHTML = MyBase.CreatePlaceHolderDesignTimeHtml()
            Return sHTML
        End Function
 
    End Class

 

 

 

image

 

step3. 覆写 RenderContents 方法

覆写 RenderContents 方法,依 Items 集合属性定义的内容,来建立相关控件,以便输出符合的 HTML 码。

        Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)
            Dim oItem As TBMenuItem
            Dim oULTag As HtmlControls.HtmlGenericControl
            Dim oLITag As HtmlControls.HtmlGenericControl
            Dim oImage As HtmlControls.HtmlImage
 
            Me.Controls.Clear()
            oULTag = New HtmlControls.HtmlGenericControl("ul")
            Me.Controls.Add(oULTag)
 
            For Each oItem In Me.Items
                oLITag = New HtmlControls.HtmlGenericControl("li")
                oULTag.Controls.Add(oLITag)
                oLITag.ID = oItem.Key
 
                oImage = New HtmlControls.HtmlImage()
                oLITag.Controls.Add(oImage)
                oImage.Src = Me.ResolveUrl(oItem.ImageUrl)
 
                oLITag.Controls.Add(New LiteralControl(oItem.Text))
            Next
 
            MyBase.RenderContents(writer)
        End Sub

 


step4. 覆写 AddAttributesToRender 方法

因为选单预设是隐藏的,按下右键才会呈现,所以我们要覆写 AddAttributesToRender 方法加上 style="display:none;"。

        Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)
            MyBase.AddAttributesToRender(writer)
            '預設為隱藏
            writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none")
        End Sub
 

step5. 覆写 Render 方法

在 TBContextMenu 加入一个 ControlID 属性,用来设定要呈现右键选单的目标控件 ID。然后覆写 Render 方法,来输出相关的 JavaScript 程序代码。

        Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            Dim oScript As StringBuilder
            Dim sScript As String
            Dim oItem As TBMenuItem
            Dim bFlag As Boolean
            Dim sClientID As String
            Dim oControl As Control
 
            oControl = WebFunc.FindControlEx(Me.Page, Me.ControlID)
            If oControl IsNot Nothing Then
                sClientID = oControl.ClientID
            Else
                sClientID = String.Empty
            End If
 
            oScript = New StringBuilder()
            oScript.AppendLine("$(document).ready(function() {")
            oScript.AppendLine("$('#" & sClientID & "').contextMenu('" & Me.ClientID & "',{")
            oScript.AppendLine("bindings: {")
            bFlag = False
            For Each oItem In Me.Items
                If StrIsNotEmpty(oItem.OnClientClick) Then
                    If bFlag Then
                        oScript.AppendLine(",")
                    End If
                    oScript.AppendLine("'" & oItem.Key & "': function(t) {")
                    oScript.AppendLine(oItem.OnClientClick)
                    oScript.AppendLine("}")
                    bFlag = True
                End If
            Next
 
            oScript.AppendLine("}")
            oScript.AppendLine("});")
            oScript.AppendLine("});")
 
            sScript = oScript.ToString
            Me.Page.ClientScript.RegisterStartupScript(Me.GetType, "menu", sScript, True)
 
            MyBase.Render(writer)
        End Sub

 

三、测试程序

接下来要测试 TBContextMenu  控件,首先在 HTML 码中加入引用相关的 jqeruy.js 及 jquery.contextmenu.js。

    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="js/jquery.contextmenu.js"></script>

 

 

 

 

在页面放置一个 Label 及一个  TBContextMenu  控件,TBContextMenu 的 ControlID 设定为此 Label,即在该 Label 按右键会出现我们设定的右键选单。

        <asp:Label  class="demo"  ID="Label1" runat="server" 
            Text="RIGHT CLICK FOR DEMO (TBContextMenu)" Font-Bold="True"></asp:Label>
        <br />
        <bee:TBContextMenu ID="TBContextMenu1" runat="server" ControlID="Label1"  >
            <Items>
                <bee:TBMenuItem Key="open" Text="Open" ImageUrl="~/image/folder.png" OnClientClick="alert('open');"/>
                <bee:TBMenuItem Key="email" Text="Email" ImageUrl="~/image/email.png" OnClientClick="alert('email');" />
                <bee:TBMenuItem Key="save" Text="Save" ImageUrl="~/image/disk.png" OnClientClick="alert('save');" />
                <bee:TBMenuItem Key="delete" Text="Delete" ImageUrl="~/image/cross.png" OnClientClick="alert('delete');" />
            </Items>
        </bee:TBContextMenu>

 

执行程序,在 Label 上按右键就会出现我们在 TBContextMenu  控件设定 Items 集合属性的选单内容。

image

 

备注:本文同步发布于「第一届iT邦帮忙铁人赛」,如果你觉得这篇文章对您有帮助,记得连上去推鉴此文增加人气 ^^
http://ithelp.ithome.com.tw/question/10013501
http://ithelp.ithome.com.tw/question/10013503

posted on 2008-11-01 00:24  jeff377  阅读(2744)  评论(8编辑  收藏  举报