前二篇文章介紹了自訂 GridView 使用的下拉清單欄位 (TBDropDownField),對如何繼承 BoundField 類別下來改寫自訂欄位應該有進一步的了解。在 GridView 中輸入日期也常蠻常見的需求,在本文將再實作一個 GridView 使用的日期欄位,在欄位儲存格使用 TBDateEdit 控制項來編輯資料。
程式碼下載:ASP.NET Server Control - Day25.rar
Northwnd 資料庫下載:NORTHWND.rar
一、繼承 TBBaseBoundField 實作 TDateField
GridView 的日期欄位需要繫結資料,一般的作法是由 BoundField 繼承下來改寫;不過我們之前已經有繼承 BoundField 製作一個 TBBaseBoundField 的自訂欄位基底類別 (詳見「 [ASP.NET 控制項實作 Day23] 自訂 GridVie 欄位類別 - 實作 TBDropDownField 欄位類別」 一文),所以我們要實作的日期欄位直接繼承 TBBaseBoundField 命名為 TDateField,並覆寫 CreateField 方法,傳回 TDateField 物件。
''' <summary>
''' 日期欄位。
''' </summary>
Public Class TBDateField
Inherits TBBaseBoundField
Protected Overrides Function CreateField() As DataControlField
Return New TBDateField()
End Function
End Class
自訂欄位類別主要是要覆寫 InitializeDataCell 方法做資料儲存格初始化、覆寫 OnDataBindField 方法將欄位值繫結至 BoundField 物件、覆寫 ExtractValuesFromCell 方法來擷取儲存格的欄位值,下面我們將針對這幾個需要覆寫的方法做一說明。
二、覆寫 InitializeDataCell 方法 - 資料儲存格初始化
首先覆寫 InitializeDataCell 方法處理資料儲存格初始化,當唯讀狀態時使用 Cell 來呈現資料;若為編輯狀態時,則在 Cell 中加入 TBDateEdit 控制項,並將 TBDateField 的屬性設定給 TBDateEdit 控制項的相關屬性。然後將儲存格 (DataControlFieldCell) 或日期控制項 (TDateEdit) 的 DataBinding 事件導向 OnDataBindField 事件處理方法。
''' <summary>
''' 資料儲存格初始化。
''' </summary>
''' <param name="Cell">要初始化的儲存格。</param>
''' <param name="RowState">資料列狀態。</param>
Protected Overrides Sub InitializeDataCell(ByVal Cell As DataControlFieldCell, ByVal RowState As DataControlRowState)
Dim oDateEdit As TBDateEdit
Dim oControl As Control
If Me.CellIsEdit(RowState) Then
'編輯狀態在儲存格加入 TBDateEdit 控制項
oDateEdit = New TBDateEdit()
oDateEdit.FirstDayOfWeek = Me.FirstDayOfWeek
oDateEdit.ShowWeekNumbers = Me.ShowWeekNumbers
oDateEdit.CalendarStyle = Me.CalendarStyle
oDateEdit.Lang = Me.Lang
oDateEdit.ShowTime = Me.ShowTime
oControl = oDateEdit
Cell.Controls.Add(oControl)
Else
oControl = Cell
End If
If (oControl IsNot Nothing) AndAlso MyBase.Visible Then
AddHandler oControl.DataBinding, New EventHandler(AddressOf Me.OnDataBindField)
End If
End Sub
TDateEdit 控制項為筆者自行撰寫的日期控制項,TDateEdit 控制項的相關細節可以參考筆者部落格下面幾篇文章有進一步說明。
日期控制項實作教學(1) - 結合 JavaScript
日期控制項實作教學(2) - PostBack 與 事件
TBDateEdit 日期控制項 - 1.0.0.0 版 (Open Source)
三、覆寫 OnDataBindField 方法 - 將欄位值繫結至 BoundField 物件
當 GridView 執行 DataBind 時,每個儲存格的 DataBinding 事件都會被導向 OnDataBindField 方法,此方法中我們會由資料來源取得指定欄位值,處理此欄位值的格式化時,將欄位值呈現在 Cell 或 TDateEdit 控制項上。
''' <summary>
''' 將欄位值繫結至 BoundField 物件。
''' </summary>
Protected Overrides Sub OnDataBindField(ByVal sender As Object, ByVal e As EventArgs)
Dim oControl As Control
Dim oDateEdit As TBDateEdit
Dim oNamingContainer As Control
Dim oDataValue As Object '欄位值
Dim bEncode As Boolean '是否編碼
Dim sText As String '格式化字串
oControl = DirectCast(sender, Control)
oNamingContainer = oControl.NamingContainer
oDataValue = Me.GetValue(oNamingContainer)
bEncode = ((Me.SupportsHtmlEncode AndAlso Me.HtmlEncode) AndAlso TypeOf oControl Is TableCell)
sText = Me.FormatDataValue(oDataValue, bEncode)
If TypeOf oControl Is TableCell Then
If (sText.Length = 0) Then
sText = " "
End If
DirectCast(oControl, TableCell).Text = sText
Else
If Not TypeOf oControl Is TBDateEdit Then
Throw New HttpException(String.Format("{0}: Wrong Control Type", Me.DataField))
End If
oDateEdit = DirectCast(oControl, TBDateEdit)
If Me.ApplyFormatInEditMode Then
oDateEdit.Text = sText
ElseIf (Not oDataValue Is Nothing) Then
oDateEdit.Text = oDataValue.ToString
End If
End If
End Sub
[超過字數限制,下一篇接續本文]
備註:本文同步發佈於筆者「ASP.NET 魔法學院」部落格
http://www.dotblogs.com.tw/jeff377/archive/2008/10/25/5772.aspx