前二篇文章介绍了自订 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 方法来撷取储存格的字段值,下面我们将针对这几个需要覆写的方法做一说明。

image

 

二、覆写 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>
''' <param name="sender">控制項。</param>
''' <param name="e">事件引數。</param>
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 = "&nbsp;"
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

 

 

四、覆写 ExtractValuesFromCell 方法 - 撷取储存格的字段值

当客户端使用 GridView 编辑后执行更新动作时,会呼叫 ExtractValuesFromCell 方法,来取得储存格的字段值,以便写入数据来源。所以我们要覆写 ExtractValuesFromCell 方法,将 Cell 或 TDateEdit 控件的值取出填入具 IOrderedDictionary 接口的对象。

 

        ''' <summary>
''' 使用指定 DataControlFieldCell 的值填入指定的 IDictionary 物件。
''' </summary>
''' <param name="Dictionary">用於儲存指定儲存格的值。</param>
''' <param name="Cell">包含要擷取值的儲存格。</param>
''' <param name="RowState">資料列的狀態。</param>
''' <param name="IncludeReadOnly">true 表示包含唯讀欄位的值,否則為 false。</param>
Public Overrides Sub ExtractValuesFromCell( _
ByVal Dictionary As IOrderedDictionary, _
ByVal Cell As DataControlFieldCell, _
ByVal RowState As DataControlRowState, _
ByVal IncludeReadOnly As Boolean)
Dim oControl As Control = Nothing
Dim sDataField As String = Me.DataField
Dim oValue As Object = Nothing
Dim sNullDisplayText As String = Me.NullDisplayText
Dim oDateEdit As TBDateEdit
If (((RowState And DataControlRowState.Insert) = DataControlRowState.Normal) OrElse Me.InsertVisible) Then
If (Cell.Controls.Count > 0) Then
oControl = Cell.Controls.Item(0)
oDateEdit = TryCast(oControl, TBDateEdit)
If (Not oDateEdit Is Nothing) Then
oValue = oDateEdit.Text
End If
ElseIf IncludeReadOnly Then
Dim s As String = Cell.Text
If (s = "&nbsp;") Then
oValue = String.Empty
ElseIf (Me.SupportsHtmlEncode AndAlso Me.HtmlEncode) Then
oValue = HttpUtility.HtmlDecode(s)
Else
oValue = s
End If
End If
If (Not oValue Is Nothing) Then
If TypeOf oValue Is String Then
If (CStr(oValue).Length = 0) AndAlso Me.ConvertEmptyStringToNull Then
oValue = Nothing
ElseIf (CStr(oValue) = sNullDisplayText) AndAlso (sNullDisplayText.Length > 0) Then
oValue = Nothing
End If
End If
If Dictionary.Contains(sDataField) Then
Dictionary.Item(sDataField) = oValue
Else
Dictionary.Add(sDataField, oValue)
End If
End If
End If
End Sub

 

五、测试程序

我们使用 Northwnd 数据库的 Employees 数据表为例,在 GridView 加入自订的 TBDateField 字段系结 BirthDate 字段,另外加入另一个 BoundField 的只读字段,也同样系结 BirthDate 字段来做比较。

 

 

            <bee:TBDateField DataField="BirthDate" HeaderText="BirthDate"
SortExpression="BirthDate" DataFormatString="{0:d}"
ApplyFormatInEditMode="True" CalendarStyle="Winter" />
<asp:BoundField DataField="BirthDate" HeaderText="BirthDate"
SortExpression="BirthDate" DataFormatString="{0:d}"
ApplyFormatInEditMode="True" ReadOnly="true" />

 

执行程序,在编辑数据列时,TBDateField 就会以 TDateEdit 控件来进行编辑。

image

使用 TDateEdit 编辑字段值后,按「更新」钮,数据就会被写回数据库。

image

 

备注:本文同步发布于「第一届iT邦帮忙铁人赛」,如果你觉得这篇文章对您有帮助,记得连上去推鉴此文增加人气 ^^
http://ithelp.ithome.com.tw/question/10013083
http://ithelp.ithome.com.tw/question/10013091

posted on 2008-10-26 18:38  jeff377  阅读(1988)  评论(1编辑  收藏  举报