您的位置:首页 > 编程语言 > ASP

[ASP.NET 控件实作 Day25] 自订 GridView 字段 - 日期字段

2008-10-26 18:38 561 查看
前二篇文章介绍了自订 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>
''' <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 = " "
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 = " ") 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 控件来进行编辑。




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




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

http://ithelp.ithome.com.tw/question/10013083

http://ithelp.ithome.com.tw/question/10013091
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: