摘要
承上一篇文章「GridView+FormView 示范资料 新增/修改/删除」,有人询问是否能简化程序代码;答案是可行的,方法就是由服务器控件下手。在此文章中,我们将扩充 GridView 及 FormView 控件,在 GridView 控件中新增 FormViewID 属性,关连至指定的 FormView 控件 ID,就可以轻易达到上篇文章中相同效果。



扩充 GridView 控件
首先我们继承 GridView 下来扩充功能,新增 FormViewID 属性,用来设定连结的 FormView 控件 ID。然后把原本在 GridView 的 RowCommand 事件中的程序代码,搬至 OnRowCommand 覆写方法中。
扩充功能的 TBGridView 控件完整程序代码如下,其中 OnLoad 方法中,会去判断 FormView 若为 TBFormView (扩充功能的 FormView),会去设定其 GridView 属性。
  1Imports System
  2Imports System.Collections.Generic
  3Imports System.ComponentModel
  4Imports System.Text
  5Imports System.Web
  6Imports System.Web.UI
  7Imports System.Web.UI.WebControls
  8Imports System.Drawing
  9
 10Namespace WebControls
 11    < _
 12    Description("TBGridView 控件"), _
 13    ToolboxData("<{0}:TBGridView runat=server></{0}:TBGridView>") _
 14    > _
 15    Public Class TBGridView
 16        Inherits GridView
 17        Private FFormViewID As String = String.Empty
 18        Private FFormView As FormView = Nothing
 19
 20        ''' <summary>
 21        ''' 连结的 FormView 控件 ID。
 22        ''' </summary>

 23        < _
 24        Description("连结的 FormView 控件 ID。"), _
 25        Themeable(False), _
 26        IDReferenceProperty(GetType(FormView)), _
 27        TypeConverter(GetType(TBFormViewIDConverter)), _
 28        Category("Data"), _
 29        DefaultValue("") _
 30        > _
 31        Public Property FormViewID() As String
 32            Get
 33                Return FFormViewID
 34            End Get
 35            Set(ByVal value As String)
 36                FFormViewID = value
 37            End Set
 38        End Property

 39
 40        ''' <summary>
 41        ''' 连结的 FormView 控件。
 42        ''' </summary>

 43        Protected Friend ReadOnly Property FormView() As FormView
 44            Get
 45                If String.IsNullOrEmpty(FFormViewID) Then Return Nothing
 46                If FFormView Is Nothing Then
 47                    FFormView = CType(Me.Parent.FindControl(FFormViewID), FormView)
 48                End If
 49                Return FFormView
 50            End Get
 51        End Property

 52
 53        ''' <summary>
 54        ''' 取得对应数据来源的数据列索引。
 55        ''' </summary>
 56        ''' <param name="RowIndex">GridView 的数据列索引。</param>

 57        Public Function GetDataRowIndex(ByVal RowIndex As IntegerAs Integer
 58            Dim iRowIndex As Integer
 59
 60            If Me.AllowPaging Then
 61                'GridView 有分页时,要把考虑目前的页数及每页笔数
 62                iRowIndex = Me.PageIndex * Me.PageSize + RowIndex
 63            Else
 64                'GridView 无分页时,直接使用 RowIndex
 65                iRowIndex = RowIndex
 66            End If
 67            Return iRowIndex
 68        End Function

 69
 70        ''' <summary>
 71        ''' 覆写。引发 Load 事件。
 72        ''' </summary>

 73        Protected Overrides Sub OnLoad(ByVal e As EventArgs)
 74            MyBase.OnLoad(e)
 75            If Me.FormView IsNot Nothing Then
 76                If TypeOf Me.FormView Is TBFormView Then
 77                    DirectCast(Me.FormView, TBFormView).GridView = Me
 78                End If
 79            End If
 80        End Sub

 81
 82        ''' <summary>
 83        ''' 覆写。引发 RowCommand 事件。
 84        ''' </summary>

 85        Protected Overrides Sub OnRowCommand(ByVal e As GridViewCommandEventArgs)
 86            Dim iDataRowIndex As Integer
 87
 88            Select Case e.CommandName.ToUpper
 89                Case "Edit".ToUpper '编辑模式
 90                    If Me.FormView IsNot Nothing Then
 91                        iDataRowIndex = GetDataRowIndex(CInt(e.CommandArgument))
 92                        Me.FormView.PageIndex = iDataRowIndex
 93                        Me.FormView.ChangeMode(FormViewMode.Edit) 'FormView 切换为编辑模式
 94                        Me.FormView.Visible = True  'FormView 显示
 95                        Me.Visible = False 'GridView 隐藏
 96                    End If
 97
 98                Case "Insert".ToUpper '新增模式
 99                    If Me.FormView IsNot Nothing Then
100                        Me.FormView.ChangeMode(FormViewMode.Insert) 'FormView 切换为新增模式
101                        Me.FormView.Visible = True  'FormView 显示
102                        Me.Visible = False 'GridView 隐藏
103                    End If
104            End Select
105            MyBase.OnRowCommand(e)
106        End Sub

107
108    End Class

109End Namespace

扩充 FormView 控件
接下来继承 FormView 下来扩充功能,首先要新增一个 GridView 属性,当 TBGridView 有设定 FormViewID 时,且 FormView 的型别为 TBFormView 时,会去设定 TBFormView.GridView 属性,让 TBFormView 控件知道系结来源的 GridView,以做后序的相关程序控管。
TBFormView 的程序代码如下,一样把原本 FormView 相关事件的程序代码搬过来控件的程序代码中。
  1Imports System
  2Imports System.Collections.Generic
  3Imports System.ComponentModel
  4Imports System.Text
  5Imports System.Web
  6Imports System.Web.UI
  7Imports System.Web.UI.WebControls
  8Imports System.Drawing
  9Imports Bee.Lib.TBLibFunc
 10
 11Namespace WebControls
 12    ''' <summary>
 13    ''' 利用使用者定义的样板,显示数据来源中单一数据录的值。支持编辑、删除及插入数据录。 
 14    ''' </summary>

 15    < _
 16    Description("TBFormView 控件"), _
 17    ToolboxData("<{0}:TBFormView runat=server></{0}:TBFormView>") _
 18    > _
 19    Public Class TBFormView
 20        Inherits FormView
 21        Private FGridView As GridView = Nothing
 22
 23        ''' <summary>
 24        ''' 连结的 GridView 控件。
 25        ''' </summary>

 26        Protected Friend Property GridView() As GridView
 27            Get
 28                Return FGridView
 29            End Get
 30            Set(ByVal value As GridView)
 31                FGridView = value
 32            End Set
 33        End Property

 34
 35        ''' <summary>
 36        ''' 递归寻找指定 ID 的控件。
 37        ''' </summary>
 38        ''' <param name="Parent">父代控件。</param>
 39        ''' <param name="CommandName">按钮命令名称。</param>
 40        ''' <returns>回传 ID 符合的控件,若未找到则传回 Nothing。</returns>

 41        Private Overloads Function FindButtonControl(ByVal Parent As System.Web.UI.Control, ByVal CommandName As StringAs IButtonControl
 42            Dim oControl As System.Web.UI.Control = Nothing
 43            Dim oButtonControl As IButtonControl = Nothing
 44
 45            For Each oControl In Parent.Controls
 46                If (TypeOf oControl Is IButtonControl) Then
 47                    oButtonControl = DirectCast(oControl, IButtonControl)
 48                    If SameText(CommandName, oButtonControl.CommandName) Then
 49                        Return oButtonControl
 50                    End If
 51                Else
 52                    If oControl.Controls.Count > 0 Then
 53                        oButtonControl = FindButtonControl(oControl, CommandName)
 54                        If oButtonControl IsNot Nothing Then
 55                            Return oButtonControl
 56                        End If
 57                    End If
 58                End If
 59            Next
 60
 61            Return Nothing
 62        End Function

 63
 64        ''' <summary>
 65        ''' 依 CommandName 寻找对应的按钮。
 66        ''' </summary>
 67        ''' <param name="CommandName">按钮命令名称。</param>

 68        Private Overloads Function FindButtonControl(ByVal CommandName As StringAs IButtonControl
 69            Return FindButtonControl(Me, CommandName)
 70        End Function

 71
 72        ''' <summary>
 73        ''' 覆写。引发 Load 事件。
 74        ''' </summary>

 75        Protected Overrides Sub OnLoad(ByVal e As EventArgs)
 76            '若预设为编辑模式,则将 InsertItemTemplate 设为 EditItemTemplate
 77            If Me.DefaultMode = FormViewMode.Edit Then
 78                Me.InsertItemTemplate = Me.EditItemTemplate
 79            End If
 80            MyBase.OnLoad(e)
 81        End Sub

 82
 83        ''' <summary>
 84        ''' 覆写。引发 PreRender 事件。
 85        ''' </summary>

 86        Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
 87            Dim oButtonControl As IButtonControl
 88
 89            MyBase.OnPreRender(e)
 90
 91            If Me.Visible AndAlso Me.GridView IsNot Nothing Then
 92                Select Case Me.CurrentMode
 93                    Case FormViewMode.Edit '编辑模式
 94                        '隐藏新增钮
 95                        oButtonControl = FindButtonControl("Insert")
 96                        If oButtonControl IsNot Nothing Then
 97                            DirectCast(oButtonControl, Control).Visible = False
 98                        End If
 99                        '显示更新钮
100                        oButtonControl = FindButtonControl("Update")
101                        If oButtonControl IsNot Nothing Then
102                            DirectCast(oButtonControl, Control).Visible = True
103                        End If
104                    Case FormViewMode.Insert
105                        '显示新增钮
106                        oButtonControl = FindButtonControl("Insert")
107                        If oButtonControl IsNot Nothing Then
108                            DirectCast(oButtonControl, Control).Visible = True
109                        End If
110                        '隐藏更新钮
111                        oButtonControl = FindButtonControl("Update")
112                        If oButtonControl IsNot Nothing Then
113                            DirectCast(oButtonControl, Control).Visible = False
114                        End If
115                End Select
116            End If
117        End Sub

118
119        ''' <summary>
120        ''' 切换为浏览模式。
121        ''' </summary>

122        Private Sub ChangeViewMode()
123            Me.Visible = False
124            Me.GridView.Visible = True
125            Me.GridView.EditIndex = -1
126        End Sub

127
128        ''' <summary>
129        ''' 覆写。引发 ItemInserted 事件。
130        ''' </summary>

131        Protected Overrides Sub OnItemInserted(ByVal e As FormViewInsertedEventArgs)
132            MyBase.OnItemInserted(e)
133            '切换为浏览模式
134            ChangeViewMode()
135        End Sub

136
137        ''' <summary>
138        ''' 覆写。引发 ItemUpdated 事件。
139        ''' </summary>

140        Protected Overrides Sub OnItemUpdated(ByVal e As FormViewUpdatedEventArgs)
141            MyBase.OnItemUpdated(e)
142            '切换为浏览模式
143            ChangeViewMode()
144        End Sub

145
146        ''' <summary>
147        ''' 覆写。引发 ItemCommand 事件。
148        ''' </summary>

149        Protected Overrides Sub OnItemCommand(ByVal e As FormViewCommandEventArgs)
150            MyBase.OnItemCommand(e)
151        End Sub

152    End Class

153
154End Namespace

使用 TBGridView 及 TBFormView 控件
以上篇的范例程序做修改,只要将 aspx 中 GridView 置换为 TBGridView,而 FormView 置换为 TBFormView,并设定 TBGridView 的 FormViewID 属性为 TBFormView 控件 ID 即可。

<bee:TBGridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
    CellPadding
="4" DataKeyNames="EmployeeID" DataSourceID="SqlDataSource1" EmptyDataText="沒有資料錄可顯示。"
    ForeColor
="#333333" GridLines="None" PageSize="5" FormViewID="FormView1">

而 aspx.vb 的程序代码可以简化如下,原本 GridView 及 FormView 相关操作的控管都可以省略掉。

 1Partial Class _Default
 2    Inherits System.Web.UI.Page
 3
 4    Protected Sub GridView1_RowDataBound(ByVal sender As ObjectByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
 5        Dim oButton As Button
 6
 7        If e.Row.RowType = DataControlRowType.DataRow Then
 8            '设定编辑钮的 CommandArgument
 9            oButton = CType(e.Row.Cells(0).FindControl("btnEdit"), Button)
10            oButton.CommandArgument = e.Row.RowIndex.ToString
11        End If
12    End Sub

13
14    Protected Sub FormView1_PreRender(ByVal sender As ObjectByVal e As System.EventArgs) Handles FormView1.PreRender
15        Dim oFormView As FormView
16        Dim oTextBox As TextBox
17
18        oFormView = CType(sender, FormView)
19        If Not oFormView.Visible Then Exit Sub
20
21        Select Case oFormView.CurrentMode
22            Case FormViewMode.Edit '编辑模式
23                '显示 EmployeeID 的 TextBox
24                oTextBox = oFormView.FindControl("txtEmployeeID")
25                oTextBox.Visible = False
26            Case FormViewMode.Insert
27                '显示 EmployeeID 的 TextBox
28                oTextBox = oFormView.FindControl("txtEmployeeID")
29                oTextBox.Visible = True
30        End Select
31    End Sub

32End Class

后记
也许有人会问,可不可以连上述的程序代码都省略了,答案也是肯定的,只要去扩充 CommandField 及 TextBox 控件就可以达到零程序代码。对于 CommandField 的部分,要让 CommandField 的 Header 有辨法放「新增」钮;而 TextBox 的部分,要让 TextBox 有辨法自行判断所在的 FormView 的 CurrentMode,自行决定本身是否要显示或隐藏。

posted on 2008-05-12 16:47  jeff377  阅读(3665)  评论(3编辑  收藏  举报