前面我们讨论过「继承 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。
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 事件。
备注:本文同步发布于「第一届iT邦帮忙铁人赛」,如果你觉得这篇文章对您有帮助,记得连上去推鉴此文增加人气 ^^
http://ithelp.ithome.com.tw/question/10012507