65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 DataGrid 动态创建行

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.24/5 (5投票s)

2008年1月16日

CPOL

4分钟阅读

viewsIcon

32565

downloadIcon

387

在 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 验证器”。

<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 来实现动态控件功能,而且耗时更少。



© . All rights reserved.