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/
以上图右键选单为例,我们看一下它的 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 的内容。
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
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 集合属性的选单内容。
备注:本文同步发布于「第一届iT邦帮忙铁人赛」,如果你觉得这篇文章对您有帮助,记得连上去推鉴此文增加人气 ^^
http://ithelp.ithome.com.tw/question/10013501
http://ithelp.ithome.com.tw/question/10013503