點部落 首頁 訂閱RSS 我的收藏 Login

ASP.NET 魔法學院

<< [ASP.NET 控制項實作 Day15] 複合控制項隱藏的問題 | Home | [ASP.NET 控制項實作 Day17] 集合屬性包含不同型別的成員 >>

[ASP.NET 控制項實作 Day16] 繼承 WebControl 實作 Toolbar 控制項

前面我們討論過「繼承 CompositeControl 實作 Toolbar 控制項」,本文將繼承 WebControl 來實作同樣功能的 Toolbar 控制項,用不同的方式來實作同一個控制項,進而比較二者之間的差異。

程式碼下載:ASP.NET Server Control - Day16.rar

 

一、繼承 WebControl 實作 TBToolbar 控制項

step1. 新增繼承 WebControl 的 TBToolbar 控制項

新增繼承 WebControl 的 TBToolbar 控制項,你也可以直接原修改原 TBToolbar 控制項,繼承對象由 CompositeControl 更改為 WebControl即可。跟之前一樣在 TBToolbar 控制項加入 Items 屬性及 Click 事件。

另外 TBToolbar 控制項需實作 INamingContainer 界面,此界面很特殊沒有任何屬性或方法,INamingContainer 界面的作用是子控制項的 ClientID 會在前面加上父控制項的 ClickID,使每個子控制項有唯一的 ClientID。

image

 

step2. 建立工具列按鈕集合

覆寫 RenderContents 方法,將原本 TBToolbar (複合控制項) 的 CreateChildControls 方法中建立工具列按鈕程式碼,搬移至 RenderContents 方法即可。

        Private Sub ButtonClickEventHandler(ByVal sender As Object, ByVal e As EventArgs)
            Dim oButton As Button
            Dim oEventArgs As ClickEventArgs

            oButton = CType(sender, Button)
            oEventArgs = New ClickEventArgs()
            oEventArgs.Key = oButton.ID
            OnClick(oEventArgs)
        End Sub

        ''' <summary>
        ''' 覆寫 RenderContents 方法。
        ''' </summary>
        Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)
            Dim oItem As TBToolbarItem
            Dim oButton As Button

            For Each oItem In Me.Items
                oButton = New Button()
                oButton.Text = oItem.Text
                oButton.Enabled = oItem.Enabled
                oButton.ID = oItem.Key
                AddHandler oButton.Click, AddressOf ButtonClickEventHandler
                Me.Controls.Add(oButton)
            Next

            If Me.Items.Count = 0 AndAlso Me.DesignMode Then
                oButton = New Button()
                oButton.Text = "請設定 Items 屬性。"
                Me.Controls.Add(oButton)
            End If

            MyBase.RenderContents(writer)
        End Sub

上述的直接搬移過來的程式碼還有個問題,就是原來的使用 AddHandler 來處理按鈕事件的方式變成沒有作用了?因為現在不是複合式控制項,當前端的按鈕 PostBack 傳回伺服端時,TBToolbar 不會事先建立子控制槓,所以機制會找不到原來產生的按鈕,也就無法使用 AddHandler 來處理事件了。

 

 

AddHandler oButton.Click, AddressOf ButtonClickEventHandler

 

step3. 處理 Click 事件

因為不能使用 AddHandler 來處理按鈕事件,所以我們就自行使用 Page.ClientScript.GetPostBackEventReference 方法來產生 PostBack 動作的用戶端指令碼,按鈕的 OnClientClick 去執行 PostBack 的動作。

 

            For Each oItem In Me.Items
                oButton = New Button()
                oButton.Text = oItem.Text
                oButton.Enabled = oItem.Enabled
                oButton.ID = oItem.Key
                sScript = Me.Page.ClientScript.GetPostBackEventReference(Me, oItem.Key)
                oButton.OnClientClick = sScript
                Me.Controls.Add(oButton)
            Next

 

TBToolar 控制項輸出的 HTML 碼如下

<span id="TBToolbar1">
<input type="submit" name="TBToolbar1$Add" value="新增" onclick="__doPostBack('TBToolbar1','Add');" id="TBToolbar1_Add" />
<input type="submit" name="TBToolbar1$Edit" value="修改" onclick="__doPostBack('TBToolbar1','Edit');" id="TBToolbar1_Edit" />
<input type="submit" name="TBToolbar1$Delete" value="刪除" onclick="__doPostBack('TBToolbar1','Delete');" id="TBToolbar1_Delete" />
</span>

 

要自行處理 PostBack 的事件,需實作 IPostBackEventHandler 介面,在 RaisePostBackEvent 方法來引發 TBToolbar 的 Click 事件。

 

    Public Class TBToolbar
        Inherits WebControl
        Implements INamingContainer
        Implements IPostBackEventHandler

        Public Sub RaisePostBackEvent(ByVal eventArgument As String) Implements System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
            Dim oEventArgs As ClickEventArgs

            oEventArgs = New ClickEventArgs()
            oEventArgs.Key = eventArgument
            Me.OnClick(oEventArgs)
        End Sub

    End Class

 

 

二、測試程式

在測試頁面上放置 TBToolbar 控制項,在 Click 事件撰寫測試程式碼。

 

    Protected Sub TBToolbar1_Click(ByVal sender As Object, ByVal e As Bee.Web.WebControls.TBToolbar.ClickEventArgs) Handles TBToolbar1.Click
        Me.Response.Write("Toolbar1 Click - " & e.Key)
    End Sub

 

當我們按了工具列上的按鈕,就會引發對應的 Cliek 事件。

image

 

備註:本文同步發佈於「第一屆iT邦幫忙鐵人賽」,如果你覺得這篇文章對您有幫助,記得連上去推鑒此文增加人氣 ^^
http://ithelp.ithome.com.tw/question/10012507

ASP.NET 魔法學院


2008/10/17 00:02| 閱讀數 : 2390 | 2 人收藏 我要推薦 | 4 Comments | 文章分類: Server Control 訂閱

DotBlogs Tags: ServerControl

關連文章

  • [ASP.NET 控制項實作 Day18] 修改集合屬性編輯器
  • [ASP.NET 控制項實作 Day17] 集合屬性包含不同型別的成員
  • [ASP.NET 控制項實作 Day15] 複合控制項隱藏的問題
  • [ASP.NET 控制項實作 Day14] 繼承 CompositeControl 實作 Toolbar 控制項
  • 擴展 CheckBoxList 控制項 - 繫結複選項目
  • 擴展 CheckBoxField 類別 - 支援非布林值的雙向繫結
  • CollectionEditor 顯示 [說明] 區域
  • 擴展 GridView 控制項 - 支援 Excel 及 Word 匯出
  • 擴展 CommandField 類別 - 刪除提示訊息
  • TBDateEdit 日期控制項 - 1.0.0.0 版 (Open Source)

Feedback

  • WizardWu 2008/10/17 上午 09:09 回覆

    # re: [ASP.NET 控制項實作 Day16] 繼承 WebControl 實作 Toolbar 控制項


    >>INamingContainer 界面的作用是子控制項的 ClientID 會在前面加上父控制項的 ClickID

    INamingContainer 界面的作用是子控制項的 ClientID 會在前面加上父控制項的 ClientID

    --------------------------

    interface 對岸稱為「接口」,台灣為「介面」;
    一般的 UI, user interface 之類的操作介面,對岸稱為「界面」,台灣為「介面」。

  • Allen Kuo 2008/10/17 上午 09:59 回覆

    # re: [ASP.NET 控制項實作 Day16] 繼承 WebControl 實作 Toolbar 控制項

    印象中我以前是用這方法寫的, 請問 Jeff 您覺得這作法與繼承 CompositeControl 的作法, 有什麼優劣, 看起來
    繼承 CompositeControl 的方法好像比較好用

  • jeff377 2008/10/17 上午 10:04 回覆

    # re: [ASP.NET 控制項實作 Day16] 繼承 WebControl 實作 Toolbar 控制項

    to WizardWu :
    你說沒錯,應該翻成介面,是筆誤為「界面」了。

  • jeff377 2008/10/17 上午 10:07 回覆

    # re: [ASP.NET 控制項實作 Day16] 繼承 WebControl 實作 Toolbar 控制項

    to Allen Kuo :
    繼承 CompositeControl 是作法有點像 UserControl,只是一個是用程式碼去建立子控制項,一個是有界面去設計。

    關於 CompositeControl 的問題,我在下面的文章有提及,可以參考看看。
    [ASP.NET 控制項實作 Day15] 複合控制項隱藏的問題

     

標題 *
名稱 *
Email (將不會被顯示)
Url
回應
登入後使用進階評論
Please add 6 and 8 and type the answer here:
文章數(170) 回應數(419) 引用數(0)


☆ 有些事現在不做,就一輩子都不會做了 ☆


文章標籤

  • API
  • BasePage
  • Calendar
  • CallBack
  • CheckBoxField
  • ClientScript
  • CommandField
  • DropDownList
  • FormView
  • GridView
  • javascript
  • ServerControl
  • SqlDataSource
  • 伺服器控制項
  • 動態建立控制項

more tags...

每月文章

  • 2010年3月 (4)
  • 2009年10月 (1)
  • 2009年1月 (1)
  • 2008年11月 (2)
  • 2008年10月 (30)
  • 2008年9月 (2)
  • 2008年8月 (10)
  • 2008年7月 (2)
  • 2008年6月 (12)
  • 2008年5月 (19)
  • 2008年4月 (6)
  • 2008年3月 (80)
  • 2008年2月 (1)

文章分類

  • AJAX (6)
  • API (5)
  • ASP.NET 基礎 (64)
  • ASP.NET 進階 (9)
  • CSS (1)
  • DataSource 控制項 (3)
  • Download (1)
  • Enterprise Library (4)
  • FormView (5)
  • GridView (35)
  • JavaScript (14)
  • jQuery (4)
  • Server Control (59)
  • User Control (1)
  • VB.NET (7)
  • 動態建立控制項 (5)
  • 常見問題 (15)
  • 軟體架構/機制 (10)

推薦部落格

  • ASP.NET 魔法學院(簡體)
  • Dotjum的分享空間
  • topcat姍舞之間的極度凝聚
  • 馬小玲的異想世界

最新回應

  • re: 頁面輸出繁簡中文轉換 你寫的眞好,眞的很感謝!
  • by HSHS
  • re: 擴展 GridView 控制項 - 無資料時顯示標題列 to Qwerty : 沒錯,伺服器控制項是給伺服端程式使用,它在輸出網頁給用戶端瀏覽時,會解譯成標....
  • by jeff
  • re: 擴展 GridView 控制項 - 無資料時顯示標題列 請問是不是所有的伺服器控制項都是以 HTML 控制項呈現在瀏覽器上? 比如我在瀏覽器檢視原始碼, 原....
  • by Qwerty
  • re: GridView 與 DetailsView 連動 - 繫結同一個 SqlDataSource to chjiang : 你可以看一下你的程式碼中是否有 new 新控制項,並使用 Controls....
  • by jeff
  • re: GridView 與 DetailsView 連動 - 繫結同一個 SqlDataSource to jeff : 真的很開心您的回覆,也很謝謝您熱心的指導:)不過,我是個asp.net初學者,所....
  • by chjiang
  • re: GridView 與 DetailsView 連動 - 繫結同一個 SqlDataSource to chjiang : 你的錯訊息是因為程式碼中有動態加入控制項,而在處理 ViewState 反....
  • by jeff
  • re: GridView 與 DetailsView 連動 - 繫結同一個 SqlDataSource 您好~想請問一下~當我按某一筆「選取」顯示在Formview 之後,我再按取消,再選取其它筆會出現以....
  • by chjiang
  • re: [ASP.NET 控制項實作 Day7] 設定工具箱的控制項圖示 to Qwerty : 若你加入專案方式來引用控制項會顯示預設圖示(齒輪圖示),若是直接引用 dll....
  • by jeff
  • re: [ASP.NET 控制項實作 Day7] 設定工具箱的控制項圖示 不知為什麼,專案重新開啟後,工具箱上面的圖示又變回預設圖示(齒輪圖示).
  • by Qwerty
  • re: 讓 ASP.NET 也可以使用 MsgBox 方法 to Arthur : 雞婆幫老師回答一下,code應該是OK的...已經使用ScriptManag....
  • by 91
Copyright © 2008 design by Iris Kang.