[ASP.NET 控制項實作 Day25] 自訂 GridView 欄位 – 日期欄位

來源:互聯網
上載者:User

前二篇文章介紹了自訂 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 TBDateFieldInherits TBBaseBoundFieldProtected Overrides Function CreateField() As DataControlFieldReturn New TBDateField()End FunctionEnd 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 TBDateEditDim oControl As ControlIf Me.CellIsEdit(RowState) Then'編輯狀態在儲存格加入 TBDateEdit 控制項oDateEdit = New TBDateEdit()oDateEdit.FirstDayOfWeek = Me.FirstDayOfWeekoDateEdit.ShowWeekNumbers = Me.ShowWeekNumbersoDateEdit.CalendarStyle = Me.CalendarStyleoDateEdit.Lang = Me.LangoDateEdit.ShowTime = Me.ShowTimeoControl = oDateEditCell.Controls.Add(oControl)ElseoControl = CellEnd IfIf (oControl IsNot Nothing) AndAlso MyBase.Visible ThenAddHandler oControl.DataBinding, New EventHandler(AddressOf Me.OnDataBindField)End IfEnd 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 ControlDim oDateEdit As TBDateEditDim oNamingContainer As ControlDim oDataValue As Object            '欄位值Dim bEncode As Boolean              '是否編碼Dim sText As String                 '格式化字串oControl = DirectCast(sender, Control)oNamingContainer = oControl.NamingContaineroDataValue = Me.GetValue(oNamingContainer)bEncode = ((Me.SupportsHtmlEncode AndAlso Me.HtmlEncode) AndAlso TypeOf oControl Is TableCell)sText = Me.FormatDataValue(oDataValue, bEncode)If TypeOf oControl Is TableCell ThenIf (sText.Length = 0) ThensText = "&nbsp;"End IfDirectCast(oControl, TableCell).Text = sTextElseIf Not TypeOf oControl Is TBDateEdit ThenThrow New HttpException(String.Format("{0}: Wrong Control Type", Me.DataField))End IfoDateEdit = DirectCast(oControl, TBDateEdit)If Me.ApplyFormatInEditMode ThenoDateEdit.Text = sTextElseIf (Not oDataValue Is Nothing) ThenoDateEdit.Text = oDataValue.ToStringEnd IfEnd IfEnd 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 = NothingDim sDataField As String = Me.DataFieldDim oValue As Object = NothingDim sNullDisplayText As String = Me.NullDisplayTextDim oDateEdit As TBDateEditIf (((RowState And DataControlRowState.Insert) = DataControlRowState.Normal) OrElse Me.InsertVisible) ThenIf (Cell.Controls.Count > 0) ThenoControl = Cell.Controls.Item(0)oDateEdit = TryCast(oControl, TBDateEdit)If (Not oDateEdit Is Nothing) ThenoValue = oDateEdit.TextEnd IfElseIf IncludeReadOnly ThenDim s As String = Cell.TextIf (s = "&nbsp;") ThenoValue = String.EmptyElseIf (Me.SupportsHtmlEncode AndAlso Me.HtmlEncode) ThenoValue = HttpUtility.HtmlDecode(s)ElseoValue = sEnd IfEnd IfIf (Not oValue Is Nothing) ThenIf TypeOf oValue Is String ThenIf (CStr(oValue).Length = 0) AndAlso Me.ConvertEmptyStringToNull ThenoValue = NothingElseIf (CStr(oValue) = sNullDisplayText) AndAlso (sNullDisplayText.Length > 0) ThenoValue = NothingEnd IfEnd IfIf Dictionary.Contains(sDataField) ThenDictionary.Item(sDataField) = oValueElseDictionary.Add(sDataField, oValue)End IfEnd IfEnd IfEnd 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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.