惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
C
Check Point Blog
Vercel News
Vercel News
Y
Y Combinator Blog
G
Google Developers Blog
P
Proofpoint News Feed
WordPress大学
WordPress大学
MongoDB | Blog
MongoDB | Blog
博客园 - 司徒正美
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
L
LangChain Blog
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
博客园_首页
B
Blog RSS Feed
The Cloudflare Blog
MyScale Blog
MyScale Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Security Blog
Microsoft Security Blog

博客园 - jeff377

使用 Sandcastle Help File Builder 制作 VS.NET 的 HELP 文件 [ASP.NET 控件实作 Day31] TBContextMenu 控件三种不同模式的 Click 动作 [ASP.NET 控件实作 Day29] 解决 DropDownList 成员 Value 值相同产生的问题 [ASP.NET 控件实作 Day28] 图形验证码控件 [ASP.NET 控件实作 Day27] 控件依 FormView CurrentMode 自行设定状态 [ASP.NET 控件实作 Day26] 让你的 GridView 与众不同 [ASP.NET 控件实作 Day25] 自订 GridView 字段 - 日期字段 [ASP.NET 控件实作 Day24] TBDropDownField 的 Items 属性的数据系结 [ASP.NET 控件实作 Day23] 自订 GridVie 字段类别 - 实作 TBDropDownField 字段类别 [ASP.NET 控件实作 Day22] 让 DropDownList 不再因项目清单不存在而造成错误 [ASP.NET 控件实作 Day21] 实作控件智能卷标 [ASP.NET 控件实作 Day20] 侦错设计阶段的程序代码 [ASP.NET 控件实作 Day19] 控件设计阶段的外观 [ASP.NET 控件实作 Day18] 修改集合属性编辑器 [ASP.NET 控件实作 Day17] 集合属性包含不同型别的成员 [ASP.NET 控件实作 Day16] 继承 WebControl 实作 Toolbar 控件 [ASP.NET 控件实作 Day15] 复合控件隐藏的问题 [ASP.NET 控件实作 Day14] 继承 CompositeControl 实作 Toolbar 控件 [ASP.NET 控件实作 Day13] Flash 控件
[ASP.NET 控件实作 Day30] 整合 jQuery ContextMenu plugin ...
jeff377 · 2008-11-01 · via 博客园 - jeff377

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