上一篇 整合 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 時,會接收成功的伺服器事件結果的用戶端事件處理常式名稱。

image 

 

二、新增 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 屬性指定的用戶端指令碼。

image

當選取 Delete2 選單項目時,會產生 PostBack 動作並引發伺服端的 Click 事件,在 Click 事件中會輸出要執行的用戶端指令碼。

image

當選取 Delete3 選單項目時,會產生 CallBack 動作並引發伺服端的 Click 事件,在 Click 事件中設定 e.CallbackResult 屬性值,並將 e.CallbackResult 的結果回傳給用戶端的 ReceiveServerData 函式來處理。

image

ASP.NET 魔法學院


DotBlogs Tags: ContextMenu jQuery ServerControl

Feedback

  • kinyo1978 2008/12/29 下午 03:40 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    jeff377您好
    又來請教你了..

    下載TBContextMenu檔案在VS2008中
    直接引用Bee.Web.dll,而工具箱中有出現圖案(類似被Mark)但無法使用.
    可否指導一下呢?

    以上 謝謝...

  • jeff377 2008/12/29 下午 04:38 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    to kinyo1978 :
    你要切換到 Web 專案的 ASP.NET 頁面時,工具箱的控制項才會是啟用狀態。

  • kinyo1978 2008/12/29 下午 04:47 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    to jeff377 :
    我已經在*.aspx的頁面下囉...
    標準的項目有出現,剛引用的沒出現.
    以上 謝謝.


  • kinyo1978 2008/12/31 上午 08:21 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    to jeff377 :您好
    程式碼下載:ASP.NET Server Control - Day31.rar
    好像跟Day30.rar一樣哦..
    依本文所指示作了下面的動作,
    我在下【TBContextMenu.vb下】:
    1>.新增了Click 事件.
    2>.實作 IPostBackEventHandler 介面
    3>.實作 ICallbackEventHandler 介面 ← 名稱 'FCallbackResult' 未宣告
    Public Function GetCallbackResult
    Public Sub RaiseCallbackEvent

    請問:
    在步驟3中出現了未宣告的錯誤,是我放錯位置了嗎.
    另外【ClickEventArgs.vb】是放在Class下呢?
    還是在控制項目錄下?

    以上 煩請指導.


  • jeff377 2008/12/31 下午 05:31 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    to kinyo1978 :
    文中的程式碼專案都是有測試過上傳,你直接開啟該專案就可直接執行,你可以參考該範例程式上的寫法。

  • kinyo1978 2009/1/12 下午 01:01 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    to jeff377 :
    感謝你的提醒,花了好幾天的時間,,目前已找出錯誤點了.
    另如果同一頁面拉TBContextMenu1,TBContextMenu2
    則TBContextMenu2按下滑鼠右鍵卻無法出現,
    是否問題出現在ContorID呢?
    可否在請你指導一下呢?
    以上謝謝.

  • kinyo1978 2009/1/16 下午 04:57 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    to jeff377:
    在下已處理完成了..感謝..
    原來是註冊的問題...

  • SAM 2009/2/25 上午 08:43 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    現在有一個挺大的問題...不知有沒有人遇過...

    在masterpage的模式套用表單的情形下,使用TBContextMenu

    會無法觸發click事件

    在單一網頁是ok的~~~

    請問大大...有沒有人有解法呢=.=" 想破頭了~~~

  • SCCY_ITSD 2009/3/20 上午 10:45 回覆

    # re: [ASP.NET 控制項實作 Day31] TBContextMenu 控制項三種不同模式的 Click 動作

    大大請問一下

    VS2008是不是已經沒有App_Code這個目錄了?(我找不到)

    所以程式碼不用集中在App_Code囉?

標題 *
名稱 *
Email (將不會被顯示)
Url
回應
登入後使用進階評論
Please add 8 and 7 and type the answer here: