一般 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 事件的概念是大同小異的。
posted @ 2007-12-14 20:31 jeff377 阅读(838) 评论(1)
编辑
在上一篇「
GridView 中的子控制項取得所屬的 GridViewRow 及 RowIndex」
文章中有提到 TemplateField 中的 ChckBox 產生 PostBack 觸發事件,若我們希望直接使用 CheckBoxField 能不能達到相同 PostBack 的效果呢?以下的範例,就是要以 CheckBoxField 來達到相同效果。
假設要執行 PostBack 的 CheckBoxField 置於 GridView 中第二個欄位(欄位索引為1)。
1 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID"
2 DataSourceID="SqlDataSource1" EmptyDataText="沒有資料錄可顯示。">
3 <Columns>
4 <asp:CommandField ShowEditButton="True" />
5 <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued" />
6 <asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True" SortExpression="ProductID" />
7 <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />
8 <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" />
9 <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" SortExpression="CategoryID" />
10 </Columns>
11 </asp:GridView>
我們必須在 GridView 的 RowCreated 事件中,抓取 CheckBoxField 欄位中的 CheckBox 控制項,設定其
AutoPostBack 為 True,並攔截它的 CheckedChanged 事件導向 CheckBox1_CheckedChanged
函式。
1 Partial Class _Default
2 Inherits System.Web.UI.Page
3
4 Protected Sub GridView1_RowCreated(ByVal sender As Object,ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
Handles GridView1.RowCreated
5 Dim oCheckBox As CheckBox
6 If e.Row.RowType = DataControlRowType.DataRow Then
7 'CheckBoxField 的欄位索引為 1
8 oCheckBox = CType(e.Row.Cells(1).Controls(0), CheckBox)
9 oCheckBox.AutoPostBack = True
10 AddHandler oCheckBox.CheckedChanged, AddressOf CheckBox1_CheckedChanged
11 End If
12 End Sub
13
14 Protected Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
15 Dim oCheckBox As CheckBox
16 Dim oGridViewRow As GridViewRow
17 Dim iRowIndex As Integer
18
19 oCheckBox = CType(sender, CheckBox)
20
21 '取得控制項所屬性 GridViewRow
22 oGridViewRow = CType(oCheckBox.BindingContainer, GridViewRow)
23
24 '取得目前 GridViewRow 的索引
25 iRowIndex = oGridViewRow.RowIndex
26 End Sub
27
28 End Class
執行程式後,你會發覺與上一篇文章有相同的效果。這種讓 GridView 欄位可引發 PostBack 的作法是適用其他如 BoundField、HyperLinkField ...等欄位。
不過注意一點,設定欄位內含控件項的動作一定要在 RowCreated 事件中處理;不能在 RowDataBound 事件中處理,因為
RowDataBound 事件只有在 GridView 執行 DataBind 的動作時才會觸發,而 RowCreated 事件是每次頁面
PostBack 時重新產生 GridView 時都會觸發。
posted @ 2007-12-14 19:39 jeff377 阅读(860) 评论(0)
编辑
假設在 GirdView 欄位的 ItemTemplate 中放置 CheckBox 控制項,然後設定該 CheckBox 的 AutoPostBack 為 True,希望在 CheckBox 的CheckedChanged 事件撰寫相關程式碼。
*.aspx 的程式碼如下
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="True" Checked='<%# Bind("Discontinued") %>'
OnCheckedChanged="CheckBox1_CheckedChanged" />
</EditItemTemplate>
一般在 CheckBox 的 CheckedChanged 事件需要它是由那個資料列的 CheckBox 所引發的 PostBack。可以撰寫如下的程式碼,取得控制項所屬的 GridViewRow 及 RowIndex。
1 Protected Sub CheckBox1_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
2 Dim oCheckBox As CheckBox
3 Dim oGridViewRow As GridViewRow
4 Dim iRowIndex As Integer
5
6 oCheckBox = CType(sender, CheckBox)
7
8 '取得控制項所屬性 GridViewRow
9 oGridViewRow = CType(oCheckBox.BindingContainer, GridViewRow)
10
11 '取得目前 GridViewRow 的索引
12 iRowIndex = oGridViewRow.RowIndex
13 End Sub
posted @ 2007-12-14 19:29 jeff377 阅读(671) 评论(7)
编辑
GridView 中 CommandField 的刪除鈕預設是沒有刪除提示訊息,一般的作法是在 GridView 的 RowDataBound 事件中找到 CommandField 中的按鈕來設定它的刪除訊息。這種方式雖然可以達到需求,不過每次使用時都要自己增加程式碼是個麻煩的動作。
為了開發上的方便,本文中示範如何擴展 CommandField 類別,透過屬性就可以輕易設定刪除提示訊息。首先繼承 CommandField 下來命名為 TBCommandField,新增一個 DeleteConfirmMessage 屬性,用來設定刪除提示訊息;覆寫 InitializeCell 方法,找到按鈕並設定刪除提示訊息。
TBCommandField 類別完整的程式碼如下
1 Imports System
2 Imports System.Collections.Generic
3 Imports System.ComponentModel
4 Imports System.Text
5 Imports System.Web
6 Imports System.Web.UI
7 Imports System.Web.UI.WebControls
8
9
10 Public Class TBCommandField
11 Inherits CommandField
12
13 Private FDeleteConfirmMessage As String = String.Empty
14
15 ''' <summary>
16 ''' 刪除詢問訊息。
17 ''' </summary>
18 Public Property DeleteConfirmMessage() As String
19 Get
20 Return FDeleteConfirmMessage
21 End Get
22 Set(ByVal value As String)
23 FDeleteConfirmMessage = value
24 End Set
25 End Property
26
27 ''' <summary>
28 ''' 初始化儲存格。
29 ''' </summary>
30 ''' <param name="cell">儲存格。</param>
31 ''' <param name="cellType"></param>
32 ''' <param name="rowState"></param>
33 ''' <param name="rowIndex"></param>
34 ''' <remarks></remarks>
35 Public Overrides Sub InitializeCell(ByVal cell As DataControlFieldCell, ByVal cellType As DataControlCellType,
ByVal rowState As DataControlRowState, ByVal rowIndex As Integer)
36 MyBase.InitializeCell(cell, cellType, rowState, rowIndex)
37 If Me.ShowDeleteButton AndAlso Me.Visible AndAlso Me.DeleteConfirmMessage <> String.Empty Then
38 SetButtonDeleteConfirm(cell)
39 End If
40 End Sub
41
42 ''' <summary>
43 ''' 設定刪除鈕的刪除訊息。
44 ''' </summary>
45 ''' <param name="Cell">儲存格。</param>
46 Private Sub SetButtonDeleteConfirm(ByVal Cell As DataControlFieldCell)
47 Dim oControl As Control
48 Dim sScript As String
49
50 sScript = "if (confirm('" & Me.DeleteConfirmMessage & "')==false) {return false;}"
51
52 For Each oControl In Cell.Controls
53 If TypeOf (oControl) Is IButtonControl Then
54 If DirectCast(oControl, IButtonControl).CommandName = "Delete" Then
55 DirectCast(oControl, WebControl).Attributes("onclick") = sScript
56 Exit Sub
57 End If
58 End If
59 Next
60 End Sub
61 End Class
62
上述程式碼中,是由
SetButtonDeleteConfirm 方法來設定刪除鈕的提示訊息。CommandField 的 ButtonType 可以為 Button、Link、Image 三者之一,依設定不同分別產生的命令鈕為 Button、LinkButton 或 ImageButton 三者之一,不過它們都具有
IButtonControl 介面,所以直接判斷 IButtonControl.CommandName 是否為 "Delete" 來判斷是否為刪除鈕,若是的話就直接設定其 Attributes("onclick") 加入刪除提示訊息。
使用 TBCommandField 的方式與 CommandField 相同,然後直接 aspx 程式碼中設定其
DeleteConfirmMessage 屬性就可以加入刪除提示訊息。
<bee:TBCommandField ShowDeleteButton="True" ShowEditButton="True" DeleteConfirmMessage="確定刪除嗎?" ButtonType="Button" />
posted @ 2007-12-14 02:38 jeff377 阅读(1675) 评论(8)
编辑