上一篇 整合 jQuery ContextMenu plugin 的右键选单控件 的文章中,我们实作了 TBContextMenu 控件;本文将以 TBContextMenu 控件为例,为选单项目加入 Click 事件,并说明三种不同模式的 Click 动作。
程序代码下载:ASP.NET Server Control - Day31.rar
一、AutoPostBack 及 AutoCallBack 属性
TBMenuItem 类别原有个 OnClientClick 属性,设定要执行的客户端指令码;此为客户端的的 Click 动作,执行指定的 JavaScript 指令码。我们在 TBMenuItem 属性新增 AutoPostBack 及 AutoCallBack 属性,分别用来设定选单项目的 PostBack 及 CallBack 动作。另外 ClientCallBack 为执行 CallBack 时,会接收成功的服务器事件结果的客户端事件处理例程名称。
二、新增 Click 事件
TBContextMenu 新增 Click 事件及 ClickEventArgs 事件自变量类别,ClickEventArgs 类别包含 Key 属性表示按钮键值,CallBackResult 属性保留给 CallBack 使用。
''' <summary>
''' Click 事件引數。
''' </summary>
Public Class ClickEventArgs
Inherits System.EventArgs
Private FKey As String = String.Empty
Private FCallbackResult As String = String.Empty
''' <summary>
''' 鍵值。
''' </summary>
Public Property Key() As String
Get
Return FKey
End Get
Set(ByVal value As String)
FKey = value
End Set
End Property
''' <summary>
''' 執行 CallBack 回傳結果。
''' </summary>
Public Property CallbackResult() As String
Get
Return FCallbackResult
End Get
Set(ByVal value As String)
FCallbackResult = value
End Set
End Property
End Class
''' <summary>
''' 按下選單所引發的事件。
''' </summary>
< _
Description("按下選單所引發的事件。") _
> _
Public Event Click(ByVal sender As Object, ByVal e As ClickEventArgs)
''' <summary>
''' 引發 Click 事件。
''' </summary>
Protected Overridable Sub OnClick(ByVal e As ClickEventArgs)
RaiseEvent Click(Me, e)
End Sub
三、实作 IPostBackEventHandler 界面
实作 IPostBackEventHandler 接口,当选单项目产生 PostBack 动作后,在 RaisePostBackEvent 方法中,取得选单项目的键值 (eventArgument 参数),并引发 Click 事件。
Public Sub RaisePostBackEvent(ByVal eventArgument As String) Implements IPostBackEventHandler.RaisePostBackEvent
Dim oEventArgs As ClickEventArgs
oEventArgs = New ClickEventArgs()
oEventArgs.Key = eventArgument
Me.OnClick(oEventArgs)
End Sub
四、实作 ICallbackEventHandler 界面
实作 ICallbackEventHandler 接口,当选单项目产生 CallBack 动作后,会先执行 RaiseCallbackEvent 方法,在此方法接收客户端传入的键值 (eventArgument 参数),并引发 Click 事件,最后会将 ClickEventArgs.CallbackResult 的结果回传到客户端,由客户端指定的事件处理例程,来处理服务器回传的结果。
Public Function GetCallbackResult() As String Implements ICallbackEventHandler.GetCallbackResult
Return FCallbackResult
End Function
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements ICallbackEventHandler.RaiseCallbackEvent
Dim oEventArgs As ClickEventArgs
oEventArgs = New ClickEventArgs()
oEventArgs.Key = eventArgument
Me.OnClick(oEventArgs)
FCallbackResult = oEventArgs.CallbackResult
End Sub
五、输出选单项目的客户端指令码
在 Render 方法中,会有一段输出程序代码来输出每个选单项目的客户端指令码;其中会透过 GetItemClientScritp 私有方法,取得指定选单项目的客户端指令码。
For Each oItem In Me.Items
sClientClick = GetItemClientScript(oItem)
If StrIsNotEmpty(sClientClick) Then
If bFlag Then
oScript.AppendLine(",")
End If
oScript.AppendLine("'" & oItem.Key & "': function(t) {")
oScript.AppendLine(sClientClick)
oScript.AppendLine("}")
bFlag = True
End If
Next
GetItemClientScritp 私有方法程序代码如下,会判断 TBMenuItem 是否设定 AutoPostBack、AutoCallBack 或 OnClientClick 属性,来决定客户端选单项目 Click 动作的行为。
Private Function GetItemClientScript(ByVal Item As TBMenuItem) As String
Dim sScript As String
If Item.AutoPostBack Then
sScript = Me.Page.ClientScript.GetPostBackEventReference(Me, Item.Key) & ";"
ElseIf Item.AutoCallBack Then
sScript = Me.Page.ClientScript.GetCallbackEventReference(Me, "'" & Item.Key & "'", Item.ClientCallBack, "''") & ";"
ElseIf StrIsNotEmpty(Item.OnClientClick) Then
sScript = Item.OnClientClick
Else
sScript = String.Empty
End If
Return sScript
End Function
六、测试程序
在页面拖曳 TBContextMenu,设定 Delete1、Delete2、Delete3 三个 TBMenuItem。其中 Delete1 设定 OnClientClick 属性;Delete2 设定 AutoPostBack 属性为 True,会以 PostBack 方法引发伺服端的 Click 事件;Delete3 设定 AutoCallBack 属性为 True,会以 CallBack 方法引发伺服端的 Click 事件,并设定 ClientCallBack 属性决定接收成功的服务器事件结果的客户端事件处理例程名称。
<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="delete1" Text="Delete1" ImageUrl="~/image/cross.png" OnClientClick="alert('client click');" />
<bee:TBMenuItem Key="delete2" Text="Delete2" ImageUrl="~/image/cross.png" AutoPostBack="true" />
<bee:TBMenuItem Key="delete3" Text="Delete3" ImageUrl="~/image/cross.png" AutoCallBack="true" ClientCallBack="ReceiveServerData"/>
</Items>
</bee:TBContextMenu>
在伺服端 Click 事件撰写测试程序代码,可以利用 Me.IsCallback 来判断目前是否在 CallBack 状态中。
Protected Sub TBContextMenu1_Click(ByVal sender As Object, ByVal e As Bee.Web.WebControls.TBContextMenu.ClickEventArgs) Handles TBContextMenu1.Click
If Not Me.IsCallback Then
Me.ClientScript.RegisterStartupScript(Me.GetType, "alert", _
String.Format("alert('PostBack Click: {0}');", e.Key), True)
Else
e.CallbackResult = e.Key
End If
End Sub
另外 Delete3 选单项目有设定 ClientCallBack="ReceiveServerData",所以 aspx 程序代码中会有 ReceiveServerData JavaScript 函式,来接收 CallBack 时由伺服端传回的结果。
<script type="text/javascript">
function ReceiveServerData(rValue) {
alert('CallBack Click: '+rValue);
};
</script>
执行程序,先选取 Delete1 选单项目,会执行在 OnClientClick 属性指定的客户端指令码。
当选取 Delete2 选单项目时,会产生 PostBack 动作并引发伺服端的 Click 事件,在 Click 事件中会输出要执行的客户端指令码。
当选取 Delete3 选单项目时,会产生 CallBack 动作并引发伺服端的 Click 事件,在 Click 事件中设定 e.CallbackResult 属性值,并将 e.CallbackResult 的结果回传给客户端的 ReceiveServerData 函式来处理。