使用 DataGrid 动态创建行






1.24/5 (5投票s)
在 ASP.Net 中,我们经常使用 ASP.Net Web 控件 Table 来动态创建控件(行)。主要原因是创建容易。大多数时候,开发人员更喜欢“System.Web.UI.WebControls.Table”而不是 DataGrid,因为它类似于 HTML 表。在我们的项目中,我们选择了
引言
本文介绍如何将 DataGrid 用作数据录入对象,而不是仅仅将其视为报告工具。
背景
在 ASP.Net 中,我们经常使用 ASP.Net Web 控件 Table 来动态创建控件(行)。主要原因是创建容易。大多数时候,开发人员更喜欢“System.Web.UI.WebControls.Table”而不是 DataGrid,因为它类似于 HTML 表。在我们的项目中,我们选择了另一种方法,我们尝试使用 DataGrid。在实现了使用 DataGrid 的解决方案后,我们觉得它不仅实现起来更简单,而且对齐和大多数 UI 功能都得到了自动处理。
在我们的项目中,我们不得不在单击“添加”按钮时生成行,并在单击“删除”行按钮时删除特定行。
使用代码
1. 创建 DataGrid 中所需控件的骨架
我们首先需要创建控件的结构/骨架。单击“添加”按钮后,控件将被创建并显示在 DataGrid 中。您可以在设计视图中创建框架,但是有经验的程序员会更喜欢在“HTML”视图中创建。
如果您希望对用户输入的数据执行任何验证,可以在“
<asp:datagrid id="dgARecord" runat="server" Width="100%" CellPadding="2" AutoGenerateColumns="False"
OnItemDataBound="dgARecord_ItemDataBound" OnDeleteCommand="dgARecord_Delete">
<ItemStyle CssClass="txthLabel"></ItemStyle>
<HeaderStyle Font-Bold="True" CssClass="btnActionh"></HeaderStyle>
<FooterStyle CssClass="btnActionh"></FooterStyle>
<Columns>
<asp:TemplateColumn HeaderText="S.No" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="15%">
<ItemStyle CssClass="ContentSpacer" Width="10%"></ItemStyle>
<ItemTemplate>
<asp:label text='<%# DataBinder.Eval(Container.DataItem, "SerialNumberA")%>' id="SerialNumberA" runat="server" EnableViewState="true" CssClass="txthLabel">
</asp:label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="HostName Value" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="25%">
<ItemStyle CssClass="ContentSpacer"></ItemStyle>
<ItemTemplate>
<asp:TextBox id="txtHostNameValueA" runat="server" CssClass="txthLabel" MaxLength="50"></asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="IPAddress Value" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="25%">
<ItemStyle CssClass="ContentSpacer"></ItemStyle>
<ItemTemplate>
<asp:TextBox id="txtIPValueA" runat="server" CssClass="txthLabel"></asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
<asp:ButtonColumn Text="Delete" ButtonType="PushButton" HeaderText="Delete Row" CommandName="Delete"
ItemStyle-HorizontalAlign="Center" ItemStyle-Width="15%">
<ItemStyle CssClass="ContentSpacer"></ItemStyle>
</asp:ButtonColumn>
</Columns>
</asp:datagrid>
<asp:RequiredFieldValidator id="lblErrorHost" Runat="server" ErrorMessage="Host Name is required." ControlToValidate="txtHostNameValue">*</asp:RequiredFieldValidator> <asp:RegularExpressionValidator ControlToValidate="txtHostNameValue" Runat="server" ErrorMessage='Your Hostname Value must be a Fully Qualified Domain name e.g. test999.ab.ad.op.com' ValidationExpression="\w+([-]\w+)*\.\w+([-]\w+)*\.\w+([-.]\w+)*" ID="regHNC">*</asp:RegularExpressionValidator>
2. 将数据集绑定到 DataGrid
我们需要显示用户输入的数据或数据库中的数据。我们有用户输入的数据,可以将用户输入的数据保存在“Session”、“ViewState”、“Application”对象中,或者创建一个数据库临时表并相应地显示它,如果网络速度不是问题并且访问应用程序的用户数量很少,可以使用此技术。
通常最好使用“Hidden”或“ViewState”对象。在我们的应用程序中,我们需要在“Add Request”和“Delete Request”页面中保留用户输入的数据,因此我们选择了“Session”变量。
在步骤 1 中,我们添加了用户创建/添加的行数。ShowGridARecord() 方法负责处理。
Public Sub ShowGridARecord() Dim dtTemp As DataTable = New DataTable Dim intCounter As Integer Dim intRowCountARecord As Integer Dim drCol As DataColumn drCol = New DataColumn("SerialNumberA") dtTemp.Columns.Add(drCol) If (ViewState("rowCntA") Is Nothing) Then intRowCountARecord = 0 Else intRowCountARecord = ViewState("rowCntA") End If For intCounter = 0 To intRowCountARecord Dim drRow As DataRow drRow = dtTemp.NewRow() drRow.Item(0) = intCounter + 1 dtTemp.Rows.Add(drRow) drRow = dtTemp.NewRow() Next dgARecord.DataSource = dtTemp.DefaultView dgARecord.DataBind() End Sub
在步骤 1 中,我们将数据插入到相应的列中 – 即用户输入的数据。ShowGridARecord() 方法的最后一行请求 DataGrid 的数据绑定。这将控制权传递给“ItemDataBound”方法。在这里,我们编写将值插入到 DataGrid 的适当控件中的代码。
Public Sub dgARecord_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgARecord.ItemDataBound HNValA = Session("HostNameArrayA") IPValA = Session("IPArrayA") If (e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.EditItem) Then Dim txtHostNameValueA As TextBox = DirectCast(e.Item.FindControl("txtHostNameValueA"), TextBox) txtHostNameValueA.Text = HNValA(e.Item.ItemIndex) Dim txtIPValueA As TextBox = DirectCast(e.Item.FindControl("txtIPValueA"), TextBox) txtIPValueA.Text = IPValA(e.Item.ItemIndex) End If End Sub
3. 动态地为控件应用 CSS 类
正如我们已经提到的,为 DataGrid 应用格式和样式非常简单,因为 ASP.Net 已经完成了大部分工作。您可以看到我们是如何轻松地为新创建的控件应用样式类的。
Private Sub dgARecord_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgARecord.ItemCreated If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then Dim myButton As Button = DirectCast(e.Item.Cells(3).Controls(0), Button) myButton.CssClass = "btnAction" End If End Sub
4. 向 DataGrid 添加行
单击“添加”按钮后,我们首先将用户输入的数据保存在“ViewState”或“Session”变量中,然后增加行数计数器。下一步是根据计数器的数量生成 DataGrid 的行/控件,然后将用户输入的(最后输入)值插入到计数器中。
Private Sub btnAddA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddA.Click If (ViewState("rowCntA") < 9) Then Dim intCounter As New Integer Dim leave As New Integer Dim intRowCountARecord As Integer leave = 0 If (ViewState("rowCntA") Is Nothing) Then intRowCountARecord = 0 Else intRowCountARecord = CType(ViewState("rowCntA"), Integer) End If For intCounter = 0 To intRowCountARecord Dim txtHNGet As TextBox txtHNGet = dgARecord.Items(intCounter).Cells(1).Controls(1) If txtHNGet.Text = "" Then HNValA(intCounter) = txtHNGet.Text.Trim leave = 1 End If HNValA(intCounter) = txtHNGet.Text Dim txtIPGet As TextBox txtIPGet = dgARecord.Items(intCounter).Cells(2).Controls(1) If txtIPGet.Text = "" Then IPValA(intCounter) = txtIPGet.Text.Trim leave = 1 End If IPValA(intCounter) = txtIPGet.Text.Trim Next If (leave = 1) Then Exit Sub End If Session("HostNameArrayA") = HNValA Session("IPArrayA") = IPValA ViewState("rowCntA") += 1 ShowGridARecord() Else lblErrorMessage.Text = "You cannot add more than 10 Request." & C_VERTICAL_SPACER End If End Sub
5. 从 DataGrid 删除行
单击“删除”按钮后,我们首先将用户输入的数据保存在“ViewState”或“Session”变量中,在此步骤中,我们保存除用户单击删除按钮的行之外的所有行的所有数据。“UpdateEntriesARecord(e.Item.ItemIndex)”负责处理此问题。之后,我们减少行数计数器。下一步是根据计数器的数量生成 DataGrid 的行/控件,然后将用户输入的(最后输入)值插入到计数器中。
Sub dgARecord_Delete(ByVal sender As Object, ByVal e As DataGridCommandEventArgs) If (ViewState("rowCntA") < 1) Then lblErrorMessage.Text = "You have to process atleast one request." & C_VERTICAL_SPACER lblErrorMessage.Visible = True Else UpdateEntriesARecord(e.Item.ItemIndex) dgCNameRecord.EditItemIndex = -1 ShowGridARecord() End If End Sub
Private Sub UpdateEntriesARecord(ByVal index As Integer) Dim intCounter As New Integer Dim intRecordCounterARecord As Integer Dim intArrayCounter As Integer intArrayCounter = 0 If (ViewState("rowCntA") Is Nothing) Then intRecordCounterARecord = 0 Else intRecordCounterARecord = CType(ViewState("rowCntA"), Integer) End If For intCounter = 0 To intRecordCounterARecord If (intCounter <> index) Then Dim txtHNGet As TextBox txtHNGet = dgARecord.Items(intCounter).Cells(1).Controls(1) HNValA(intArrayCounter) = txtHNGet.Text.Trim Dim txtIPGet As TextBox txtIPGet = dgARecord.Items(intCounter).Cells(2).Controls(1) IPValA(intArrayCounter) = txtIPGet.Text.Trim intArrayCounter += 1 End If Next Session("HostNameArrayA") = HNValA Session("IPArrayA") = IPValA ViewState("rowCntA") -= 1 End Sub
优点
1) 格式化和应用新创建控件样式所需的时间更少
2) 实现简单
缺点
1) 性能主要是使用 DataGrid 时需要考虑的问题。但是,如果我们禁用页面级别的“EnableViewState”属性,可以提高性能。
结论
1) 请注意,使用 ASP.Net Tables 也可以实现类似的功能。BOK 的目的是仅仅表明我们可以使用 DataGrid 来实现动态控件功能,而且耗时更少。