Calendar 動態產生子控制項的 Event Handler

一般 Calender 都是在 DayRender 事件中依需求加入子控制項,若有個需求要在 Calender 的每日的儲存格中加入一個按鈕,並希望按下這個按鈕能引發該按鈕的 Click 事件,此在事件中撰寫相關程式碼。

以上需求最直覺的方式就是新增一個 Button  加入 Cell 中,並使用 AddHandler 來設定 Click 事件的處理函式,程式碼如下。

 1       Protected   Sub  Calendar1_DayRender( ByVal  sender  As   Object ByVal  e  As  System.Web.UI.WebControls.DayRenderEventArgs)
           Handles
 Calendar1.DayRender
 2           Dim  oButton  As   New  Button()
 3          oButton.Text  =   " 刪除 "
 4           AddHandler  oButton.Click,  AddressOf  Button_Click  ' 設定 Button Click 處理函式
 5          e.Cell.Controls.Add(oButton)
 6       End Sub
 7 
 8       ' '' <summary>
 9       ' '' Button Click 事件的處理函式
10       ' '' </summary>
11       Private   Sub  Button_Click( ByVal  sender  As   Object ByVal  e  As  System.EventArgs)
12           ' 撰寫 Button Click 的程式碼
13       End Sub

可是上面的執行結果會跟你想像的不一樣,當 Button 產生 PostBack 並不會進入指定 Button_Click 方法。 這是為什麼呢?因 為在 Calender 的 DayRender 事件動作產生的子控制項並不會被保留,你可以在 Page Load 事件中去查看 Calendar.Controls.Count 會是等於 0。由 PostBack  引發的控制項事件是去依 Request.Form  中資料跟控制項做比較決定是否引發相關事件,而該子控制項根本不存在,更不可能有機會引發它的 Click 事件了。

針對以上的問題,可以利用另一種方式來決定,就是按鈕直接呼叫 __doPostBack() 傳入 __EVENTTARGET 及 __EVENTARGUMENT 引數,然後在伺服端自行處理 PostBack 的回傳。

所以我們改使用 HtmlButton,並在 Attributes("onclick")  直接呼叫 __doPostBack() 函式,其中 __EVENTTARGET 設定為 "CalendarDelete" 做為識別,__EVENTARGUMENT 傳入日期。在 Page Load 時,利用 Me.Request.Form("__EVENTTARGET") 判斷是否由該按鈕產生的 PostBack 並導向 CalendarDelete 方法。

 1       Protected   Sub  Calendar1_DayRender( ByVal  sender  As   Object ByVal  e  As  System.Web.UI.WebControls.DayRenderEventArgs)
           Handles
 Calendar1.DayRender
 2           Dim  oButton  As  HtmlButton
 3 
 4          oButton  =   New  HtmlButton()
 5          oButton.InnerText  =   " 刪除 "
 6          oButton.Attributes( " onclick " =   " __doPostBack('CalendarDelete',' "   &  e.Day.Date.ToShortDateString()  &   " '); "
 7          e.Cell.Controls.Add(oButton)
 8       End Sub
 9 
10       Protected   Sub  Page_Load( ByVal  sender  As   Object ByVal  e  As  System.EventArgs)  Handles   Me .Load
11           If   Me .Request.Form( " __EVENTTARGET " =   " CalendarDelete "   Then
12               Dim  oDate  As   Date
13              oDate  =   Date .Parse( Me .Request.Form( " __EVENTARGUMENT " ))
14              CalendarDelete(oDate)
15           End   If
16 
17       End Sub
18 
19       ' '' <summary>
20       ' '' Calendar 刪除按鈕的處理方法。
21       ' '' </summary>
22       ' '' <param name="Value">日期。</param>
23       Private   Sub  CalendarDelete( ByVal  Value  As   Date )
24           ' 撰寫刪除的相關程式碼
25       End Sub

以上實作的方式,若你會撰寫伺服器控制項的話,甚至可以繼承 Calendar 下來改寫,定義 DayDelete、DayUpdate 或 DayCommand 等事件,在使用上就會更簡便了。這樣做法就如同 GridView 上的 CommandField 會引發 RowCommand 事件的概念是大同小異的。


你可能感兴趣的:(calendar)