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

扩充 GridView 控件
首先我们继承 GridView 下来扩充功能,新增 FormViewID 属性,用来设定连结的 FormView 控件 ID。然后把原本在 GridView 的 RowCommand 事件中的程序代码,搬至 OnRowCommand 覆写方法中。
扩充功能的 TBGridView 控件完整程序代码如下,其中 OnLoad 方法中,会去判断 FormView 若为 TBFormView (扩充功能的 FormView),会去设定其 GridView 属性。
扩充 FormView 控件
接下来继承 FormView 下来扩充功能,首先要新增一个 GridView 属性,当 TBGridView 有设定 FormViewID 时,且 FormView 的型别为 TBFormView 时,会去设定 TBFormView.GridView 属性,让 TBFormView 控件知道系结来源的 GridView,以做后序的相关程序控管。
TBFormView 的程序代码如下,一样把原本 FormView 相关事件的程序代码搬过来控件的程序代码中。
<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">
承上一篇文章「GridView+FormView 示范资料 新增/修改/删除」,有人询问是否能简化程序代码;答案是可行的,方法就是由服务器控件下手。在此文章中,我们将扩充 GridView 及 FormView 控件,在 GridView 控件中新增 FormViewID 属性,关连至指定的 FormView 控件 ID,就可以轻易达到上篇文章中相同效果。
扩充 GridView 控件
首先我们继承 GridView 下来扩充功能,新增 FormViewID 属性,用来设定连结的 FormView 控件 ID。然后把原本在 GridView 的 RowCommand 事件中的程序代码,搬至 OnRowCommand 覆写方法中。
扩充功能的 TBGridView 控件完整程序代码如下,其中 OnLoad 方法中,会去判断 FormView 若为 TBFormView (扩充功能的 FormView),会去设定其 GridView 属性。
1
Imports System
2
Imports System.Collections.Generic
3
Imports System.ComponentModel
4
Imports System.Text
5
Imports System.Web
6
Imports System.Web.UI
7
Imports System.Web.UI.WebControls
8
Imports System.Drawing
9
10
Namespace 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 Integer) As 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
109
End Namespace
Imports System2
Imports System.Collections.Generic3
Imports System.ComponentModel4
Imports System.Text5
Imports System.Web6
Imports System.Web.UI7
Imports System.Web.UI.WebControls8
Imports System.Drawing9

10
Namespace WebControls11
< _12
Description("TBGridView 控件"), _13
ToolboxData("<{0}:TBGridView runat=server></{0}:TBGridView>") _14
> _15
Public Class TBGridView16
Inherits GridView17
Private FFormViewID As String = String.Empty18
Private FFormView As FormView = Nothing19

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 String32
Get33
Return FFormViewID34
End Get35
Set(ByVal value As String)36
FFormViewID = value37
End Set38
End Property39

40
''' <summary>41
''' 连结的 FormView 控件。42
''' </summary>43
Protected Friend ReadOnly Property FormView() As FormView44
Get45
If String.IsNullOrEmpty(FFormViewID) Then Return Nothing46
If FFormView Is Nothing Then47
FFormView = CType(Me.Parent.FindControl(FFormViewID), FormView)48
End If49
Return FFormView50
End Get51
End Property52

53
''' <summary>54
''' 取得对应数据来源的数据列索引。55
''' </summary>56
''' <param name="RowIndex">GridView 的数据列索引。</param>57
Public Function GetDataRowIndex(ByVal RowIndex As Integer) As Integer58
Dim iRowIndex As Integer59

60
If Me.AllowPaging Then61
'GridView 有分页时,要把考虑目前的页数及每页笔数62
iRowIndex = Me.PageIndex * Me.PageSize + RowIndex63
Else64
'GridView 无分页时,直接使用 RowIndex65
iRowIndex = RowIndex66
End If67
Return iRowIndex68
End Function69

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 Then76
If TypeOf Me.FormView Is TBFormView Then77
DirectCast(Me.FormView, TBFormView).GridView = Me78
End If79
End If80
End Sub81

82
''' <summary>83
''' 覆写。引发 RowCommand 事件。84
''' </summary>85
Protected Overrides Sub OnRowCommand(ByVal e As GridViewCommandEventArgs)86
Dim iDataRowIndex As Integer87

88
Select Case e.CommandName.ToUpper89
Case "Edit".ToUpper '编辑模式90
If Me.FormView IsNot Nothing Then91
iDataRowIndex = GetDataRowIndex(CInt(e.CommandArgument))92
Me.FormView.PageIndex = iDataRowIndex93
Me.FormView.ChangeMode(FormViewMode.Edit) 'FormView 切换为编辑模式94
Me.FormView.Visible = True 'FormView 显示95
Me.Visible = False 'GridView 隐藏96
End If97

98
Case "Insert".ToUpper '新增模式99
If Me.FormView IsNot Nothing Then100
Me.FormView.ChangeMode(FormViewMode.Insert) 'FormView 切换为新增模式101
Me.FormView.Visible = True 'FormView 显示102
Me.Visible = False 'GridView 隐藏103
End If104
End Select105
MyBase.OnRowCommand(e)106
End Sub107

108
End Class109
End Namespace扩充 FormView 控件
接下来继承 FormView 下来扩充功能,首先要新增一个 GridView 属性,当 TBGridView 有设定 FormViewID 时,且 FormView 的型别为 TBFormView 时,会去设定 TBFormView.GridView 属性,让 TBFormView 控件知道系结来源的 GridView,以做后序的相关程序控管。
TBFormView 的程序代码如下,一样把原本 FormView 相关事件的程序代码搬过来控件的程序代码中。
1
Imports System
2
Imports System.Collections.Generic
3
Imports System.ComponentModel
4
Imports System.Text
5
Imports System.Web
6
Imports System.Web.UI
7
Imports System.Web.UI.WebControls
8
Imports System.Drawing
9
Imports Bee.Lib.TBLibFunc
10
11
Namespace 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 String) As 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 String) As 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
154
End Namespace
Imports System2
Imports System.Collections.Generic3
Imports System.ComponentModel4
Imports System.Text5
Imports System.Web6
Imports System.Web.UI7
Imports System.Web.UI.WebControls8
Imports System.Drawing9
Imports Bee.Lib.TBLibFunc10

11
Namespace WebControls12
''' <summary>13
''' 利用使用者定义的样板,显示数据来源中单一数据录的值。支持编辑、删除及插入数据录。 14
''' </summary>15
< _16
Description("TBFormView 控件"), _17
ToolboxData("<{0}:TBFormView runat=server></{0}:TBFormView>") _18
> _19
Public Class TBFormView20
Inherits FormView21
Private FGridView As GridView = Nothing22

23
''' <summary>24
''' 连结的 GridView 控件。25
''' </summary>26
Protected Friend Property GridView() As GridView27
Get28
Return FGridView29
End Get30
Set(ByVal value As GridView)31
FGridView = value32
End Set33
End Property34

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 String) As IButtonControl42
Dim oControl As System.Web.UI.Control = Nothing43
Dim oButtonControl As IButtonControl = Nothing44

45
For Each oControl In Parent.Controls46
If (TypeOf oControl Is IButtonControl) Then47
oButtonControl = DirectCast(oControl, IButtonControl)48
If SameText(CommandName, oButtonControl.CommandName) Then49
Return oButtonControl50
End If51
Else52
If oControl.Controls.Count > 0 Then53
oButtonControl = FindButtonControl(oControl, CommandName)54
If oButtonControl IsNot Nothing Then55
Return oButtonControl56
End If57
End If58
End If59
Next60

61
Return Nothing62
End Function63

64
''' <summary>65
''' 依 CommandName 寻找对应的按钮。66
''' </summary>67
''' <param name="CommandName">按钮命令名称。</param>68
Private Overloads Function FindButtonControl(ByVal CommandName As String) As IButtonControl69
Return FindButtonControl(Me, CommandName)70
End Function71

72
''' <summary>73
''' 覆写。引发 Load 事件。74
''' </summary>75
Protected Overrides Sub OnLoad(ByVal e As EventArgs)76
'若预设为编辑模式,则将 InsertItemTemplate 设为 EditItemTemplate77
If Me.DefaultMode = FormViewMode.Edit Then78
Me.InsertItemTemplate = Me.EditItemTemplate79
End If80
MyBase.OnLoad(e)81
End Sub82

83
''' <summary>84
''' 覆写。引发 PreRender 事件。85
''' </summary>86
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)87
Dim oButtonControl As IButtonControl88

89
MyBase.OnPreRender(e)90

91
If Me.Visible AndAlso Me.GridView IsNot Nothing Then92
Select Case Me.CurrentMode93
Case FormViewMode.Edit '编辑模式94
'隐藏新增钮95
oButtonControl = FindButtonControl("Insert")96
If oButtonControl IsNot Nothing Then97
DirectCast(oButtonControl, Control).Visible = False98
End If99
'显示更新钮100
oButtonControl = FindButtonControl("Update")101
If oButtonControl IsNot Nothing Then102
DirectCast(oButtonControl, Control).Visible = True103
End If104
Case FormViewMode.Insert105
'显示新增钮106
oButtonControl = FindButtonControl("Insert")107
If oButtonControl IsNot Nothing Then108
DirectCast(oButtonControl, Control).Visible = True109
End If110
'隐藏更新钮111
oButtonControl = FindButtonControl("Update")112
If oButtonControl IsNot Nothing Then113
DirectCast(oButtonControl, Control).Visible = False114
End If115
End Select116
End If117
End Sub118

119
''' <summary>120
''' 切换为浏览模式。121
''' </summary>122
Private Sub ChangeViewMode()123
Me.Visible = False124
Me.GridView.Visible = True125
Me.GridView.EditIndex = -1126
End Sub127

128
''' <summary>129
''' 覆写。引发 ItemInserted 事件。130
''' </summary>131
Protected Overrides Sub OnItemInserted(ByVal e As FormViewInsertedEventArgs)132
MyBase.OnItemInserted(e)133
'切换为浏览模式134
ChangeViewMode()135
End Sub136

137
''' <summary>138
''' 覆写。引发 ItemUpdated 事件。139
''' </summary>140
Protected Overrides Sub OnItemUpdated(ByVal e As FormViewUpdatedEventArgs)141
MyBase.OnItemUpdated(e)142
'切换为浏览模式143
ChangeViewMode()144
End Sub145

146
''' <summary>147
''' 覆写。引发 ItemCommand 事件。148
''' </summary>149
Protected Overrides Sub OnItemCommand(ByVal e As FormViewCommandEventArgs)150
MyBase.OnItemCommand(e)151
End Sub152
End Class153

154
End 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 相关操作的控管都可以省略掉。
1
Partial Class _Default
2
Inherits System.Web.UI.Page
3
4
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal 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 Object, ByVal 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
32
End Class
Partial Class _Default2
Inherits System.Web.UI.Page3

4
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound5
Dim oButton As Button6

7
If e.Row.RowType = DataControlRowType.DataRow Then8
'设定编辑钮的 CommandArgument9
oButton = CType(e.Row.Cells(0).FindControl("btnEdit"), Button)10
oButton.CommandArgument = e.Row.RowIndex.ToString11
End If12
End Sub13

14
Protected Sub FormView1_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles FormView1.PreRender15
Dim oFormView As FormView16
Dim oTextBox As TextBox17

18
oFormView = CType(sender, FormView)19
If Not oFormView.Visible Then Exit Sub20

21
Select Case oFormView.CurrentMode22
Case FormViewMode.Edit '编辑模式23
'显示 EmployeeID 的 TextBox24
oTextBox = oFormView.FindControl("txtEmployeeID")25
oTextBox.Visible = False26
Case FormViewMode.Insert27
'显示 EmployeeID 的 TextBox28
oTextBox = oFormView.FindControl("txtEmployeeID")29
oTextBox.Visible = True30
End Select31
End Sub32
End Class后记
也许有人会问,可不可以连上述的程序代码都省略了,答案也是肯定的,只要去扩充 CommandField 及 TextBox 控件就可以达到零程序代码。对于 CommandField 的部分,要让 CommandField 的 Header 有辨法放「新增」钮;而 TextBox 的部分,要让 TextBox 有辨法自行判断所在的 FormView 的 CurrentMode,自行决定本身是否要显示或隐藏。

浙公网安备 33010602011771号