前言
在「撰写自用 Confirm 方法」一文中提到的「案例三:先执行伺服端程序再弹出询问讯息,依客户端响应再接续执行」,当客户端响应询问讯息后,会呼叫 __doPostBack() 函式来产生 PostBack 的动作,页面再自行判断 Me.Request.Form("__EVENTTARGET") 及 Me.Request.Form("__EVENTARGUMENT") 来处理后序的作业。可是这样处理 PostBack 的方式略显麻烦,换个角度思考,若 Page 也能像 GridView 一样具有类似 RowCommand 的事件,可以处理这类的 PostBack 那不是更方便了吗?所以本文将在 BasePage 加入 PageCommand 事件,针对这个案例改用 PageCommand 来处理。
程序实作
我们将使用「撰写自用的 ScriptManager 来管理客户端指令码」文中提及的 TBBasePage 类别及 TBScriptManager 类别为基础做扩展。首先在 TBBasePage 新增一个 PageCommand 事件,作法如下。
1.定义 PageCommand 事件。
2.新增 EventTarget 只读属性,传回 Me.Request.Form("__EVENTTARGET")。
3.新增 EventArgument 只读属性,传回 Me.Request.Form("__EVENTARGUMENT")。
4.覆写 OnLoad 方法,判断 EventTarget 及 EventArgument 属性值,来决定是否引发 PageCommand 事件。
''' 页面基础类别。
''' </summary>
Public Class TBBasePage
Inherits System.Web.UI.Page
#Region " PageCommand 事件 "
''' <summary>
''' DayCommand 事件自变量。
''' </summary>
Public Class PageCommandEventArgs
Inherits System.EventArgs
Private FCommandName As String = String.Empty
Private FCommandArgument As String = String.Empty
''' <summary>
''' 命令名称。
''' </summary>
Public Property CommandName() As String
Get
Return FCommandName
End Get
Set(ByVal value As String)
FCommandName = value
End Set
End Property
''' <summary>
''' 命令自变量。
''' </summary>
Public Property CommandArgument() As String
Get
Return FCommandArgument
End Get
Set(ByVal value As String)
FCommandArgument = value
End Set
End Property
End Class
''' <summary>
''' 页面命令事件。
''' </summary>
< _
System.ComponentModel.Description("页面命令事件。") _
> _
Public Event PageCommand(ByVal sender As Object, ByVal e As PageCommandEventArgs)
''' <summary>
''' 引发 PageCommand 事件。
''' </summary>
Protected Overridable Sub OnPageCommand(ByVal e As PageCommandEventArgs)
RaiseEvent PageCommand(Me, e)
End Sub
#End Region
''' <summary>
''' 触发 PostBack 的控件 UniqueID。
''' </summary>
Public ReadOnly Property EventTarget() As String
Get
Return Me.Request.Form("__EVENTTARGET")
End Get
End Property
''' <summary>
''' 触发 PostBack 动作事件自变量 。
''' </summary>
Public ReadOnly Property EventArgument() As String
Get
Return Me.Request.Form("__EVENTARGUMENT")
End Get
End Property
''' <summary>
''' 判断二字符串是否相同(不区分大小写)。
''' </summary>
''' <param name="S1">第一个字符串。</param>
''' <param name="S2">第二个字符串。</param>
Public Shared Function SameText(ByVal S1 As String, ByVal S2 As String) As Boolean
If S1 Is Nothing Then
Return S2 Is Nothing
End If
Return S1.Equals(S2, StringComparison.CurrentCultureIgnoreCase)
End Function
''' <summary>
''' 覆写。引发 Load 事件。
''' </summary>
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
Dim oArgument() As String
Dim oEventArgs As PageCommandEventArgs
MyBase.OnLoad(e)
If SameText(Me.EventTarget, Me.UniqueID) Then
'引发 PageCommand 事件
oArgument = Split(Me.EventArgument, "$")
If oArgument.Length = 3 Then
If SameText(oArgument(0), "PageCommand") Then
oEventArgs = New PageCommandEventArgs()
oEventArgs.CommandName = oArgument(1)
oEventArgs.CommandArgument = oArgument(2)
Me.OnPageCommand(oEventArgs)
End If
End If
End If
End Sub
End Class
然后在 TBScriptManager 类别新增一个 GetPageCommandEventReference 方法,取得引发 PageCommand 事件的客户端指令码。
''' 用戶端指令碼管理。
''' </summary>
Public Class TBScriptManager
''' <summary>
''' 取得引發 PageCommand 事件的用戶端指令碼。
''' </summary>
''' <param name="CommandName">命令名稱。</param>
''' <param name="CommandArgument">命令引數。</param>
Public Function GetPageCommandEventReference(ByVal CommandName As String, ByVal CommandArgument As String) As String
Dim sArgument As String
sArgument = String.Format("{0}${1}${2}", "PageCommand", CommandName, CommandArgument)
Return Me.GetPostBackEventReference(FPage, sArgument)
End Function
End Class
PageCommand 事件完成了,我们把「案例三:先执行伺服端程序再弹出询问讯息,依客户端响应再接续执行」使用 PageCommand 来改写,它的程序流程如下。
请假单储存(伺服端) -> 弹出询问讯息(客户端) -> 取得客户端响应决定是否送审(伺服端)
第一个阶段处理「请假单储存(伺服端) -> 弹出询问讯息(客户端) 」,在下面的程序代码中,讯问讯息的响应结果无论是「确定」或「取消」都会引发 PageCommand 事件,CommandName 都是 "SaveConfirm",差别是 CommandArgument 的值不同。
Dim sTrueScript As String
Dim sFalseScript As String
'执行请假单储存的程序代码
'储存完成弹出询问讯息
sTrueScript = Me.BeeScript.GetPageCommandEventReference("SaveConfirm", "True")
sFalseScript = Me.BeeScript.GetPageCommandEventReference("SaveConfirm", "False")
Me.BeeScript.Confirm("假单要送审吗?", sTrueScript, sFalseScript)
End Sub
第二阶段在 PageCommand 事件处理客户端询问讯息的响应「取得客户端响应决定是否送审(伺服端)」,在 PageCommand 事件中,我们只需判断 e.CommandName 及 e.CommandArgument 来决定接续的执行动作即可。
If String.Equals(e.CommandName, "SaveConfirm", StringComparison.CurrentCultureIgnoreCase) Then
If String.Equals(e.CommandArgument, "True", StringComparison.CurrentCultureIgnoreCase) Then
'按了确定要执行的程序代码
Else
'按了取消要执行的程序代码
End If
End If
End Sub