在 Gridview 中插入行

Insert Rows In Gridview

我有一个标准的 Gridview,它是从 SQLDataSource 填充的。 Gridview 将始终有 17 行。任何人都可以给我一个如何在指定的行点手动插入行的例子吗?例如,在第 3 行和第 5 行中插入一个新行。

谢谢

嗯,完全不清楚为什么说在第 5 行或第 8 行插入在这里很重要?

还记得,当我们使用桌面 PC 时 - 单用户,或者说使用打孔卡吗?

然后输入数据的顺序很重要。但是,我们现在不使用穿孔卡,因此从数据库的角度来看,此类数据的顺序并不重要。我的意思是,如果您有多个用户输入数据,而我在第 5 行插入,那么如果其他 3 个用户也这样做会怎样。现在该记录位于第 8 位。因此,引入一个“命令”或一些“位置”需要一些进一步的上下文——换句话说,这里的目标是什么?

使用数据库时,首要规则是数据没有顺序。如果您需要某种顺序,比如输入日期,甚至是添加新记录的顺序,那么您的开发人员需要将其设计到您的软件中。

现在,说了以上?当然,有 class 问题或说 UI 接口类型的问题,其中您可能会说订购 5 个盒子,并且您需要为用户提供 re-order 这 5 个盒子的能力您希望的任何顺序的项目。

好的,上面说了这么多?

嗯,首先不清楚记录是如何输入的。并且不清楚第 5 个位置的记录如何应该是第 5 个记录。

好了,现在不管上面这些了?

添加行、删除行或插入数据的技巧?在数据级别执行此操作,而不是在 gridview 级别执行此操作。这样不仅分出了UI层,还有数据层?它还可以节省世界贫困和大量复杂代码。

因此,假设我们有一个名为“myorder”的列。如果您在 table 中没有此列,那么您真的非常需要添加它,因为正如我所说,某些数据顺序并不存在,但实际上必须“设计”并且由你这个开发者“管理”!!!

所以,让我们像这样使用一个简单的 gv:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ID" CssClass="table borderhide" >
    <Columns>
        <asp:TemplateField HeaderText="First" ><ItemTemplate>
                <asp:TextBox ID="txtFirst" runat="server" Text='<%# Eval("FirstName") %>' Width="80px">
                </asp:TextBox>
        </ItemTemplate></asp:TemplateField>
        <asp:TemplateField HeaderText="Last"><ItemTemplate>
                <asp:TextBox ID="txtLast" runat="server" Text='<%# Eval("LastName") %>' Width="80px">
                </asp:TextBox>
            </ItemTemplate></asp:TemplateField>
        <asp:TemplateField HeaderText="Hotel"><ItemTemplate>
                <asp:TextBox ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>'></asp:TextBox>
            </ItemTemplate></asp:TemplateField>
        <asp:TemplateField HeaderText="Description" ><ItemTemplate>
                <asp:TextBox ID="txtDescription" runat="server" Text='<%# Eval("Description") %>'
                    TextMode="MultiLine" Rows="3" Columns="45" 
                    ></asp:TextBox>
            </ItemTemplate></asp:TemplateField>
        <asp:TemplateField HeaderText="Active" ItemStyle-HorizontalAlign="Center" ><ItemTemplate>
            <asp:CheckBox ID="chkActive" runat="server" Checked='<%# Eval("Active") %>'  />
            </ItemTemplate></asp:TemplateField>

    </Columns>
</asp:GridView>

好的,我们的代码加载网格。如前所述,我们将为网格保留数据源,因为我们需要进行这些插入。

所以,我们要加载的代码:

Dim rstData As New DataTable

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then

        LoadData()
        LoadGrid()
    Else
        rstData = ViewState("rstData")
    End If

End Sub

Sub LoadData()
    Using conn As New SqlConnection(My.Settings.TEST4)

        Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY MyOrder"
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using

End Sub

Sub LoadGrid()

    rstData.DefaultView.Sort = "MyOrder"
    GridView1.DataSource = rstData
    GridView1.DataBind()

    RowCount.Value = rstData.Rows.Count
    ViewState("rstData") = rstData

End Sub

现在我们有了这个:

所以,现在我们有了那个添加按钮。该按钮会将行添加到网格中,并提示我们输入位置(要插入的行)。

所以,按钮看起来像这样:

        <asp:Button ID="cmdSave" runat="server" Text="Save Changes"  style="float:left" CssClass="btn"/>
        <asp:Button ID="cmdAddRow" runat="server" Text="+Add New"  style="float:right" CssClass="btn"
            OnClientClick="return askwhatrow(this);"
            />

        <asp:HiddenField ID="WhatRow" runat="server"  ClientIDMode="Static"/>
        <asp:HiddenField ID="RowCount" runat="server" ClientIDMode="Static"/>

        <script>
            function askwhatrow(btn) {

                MyRowCount = $('#RowCount').val()

                strMsg = "There are row 1 to " + MyRowCount + "\n" +
                         "What row to insert new record?"

                strAns = prompt(strMsg)
                if (strAns === null) {
                    return false
                }

                if ((strAns < 1)  || (strAns > MyRowCount) ) {
                    alert("only 1 to " + MyRowCount + " is allowed")
                    return false
                }

                // ok, set the row insert location, and run our server side buttion
                $('#WhatRow').val(strAns)
                return true
            }

        </script>

所以,当我们点击添加行时,我们得到这个提示:

我当然输入了 2(或者您的例子中的 5)。

js 代码会提示用户,但如果用户点击取消,那么按钮代码(服务器后面的代码)将不会 运行。添加数据行的代码现在如下所示:

Protected Sub cmdAddRow_Click(sender As Object, e As EventArgs) Handles cmdAddRow.Click

    ' add new row to grid at location choosen by user:
    GridToTable()     ' save any possbile edits by user

    Dim InsertLocation As Integer = WhatRow.Value

    For Each OneRow In rstData.Rows
        If Int(OneRow("MyOrder")) >= InsertLocation Then
            OneRow("MyOrder") += 1
        End If
    Next

    ' setup new row - some defaults
    Dim NewRow As DataRow = rstData.NewRow
    NewRow("MyOrder") = InsertLocation
    NewRow("Active") = False
    rstData.Rows.Add(NewRow)

    LoadGrid()

End Sub

再次注意添加该行数据是多么容易。那是因为我们将行添加到 table,然后简单地 re-bind 网格以显示该新记录。换句话说,不要试图操纵 gv,而只能操纵数据!!! (这样我们就可以拯救世界贫困和你因不得不编写太多代码而挨饿)。

所以,在我们完成上述操作后,我们会看到:

所以,有了上面的网格?您可以四处切换(几乎像 excel)。您可以编辑任何行,进行任何您想要的更改。

然后我们就有了一个保存按钮。所做的只是将 gv 数据发送回 table,然后在一个操作中将数据发送回数据库。

代码如下:

Protected Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click
    GridToTable()

    Using conn As New SqlConnection(My.Settings.TEST4)

        Dim strSQL = "SELECT * FROM tblHotelsA"
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            Dim da As New SqlDataAdapter(cmdSQL)
            Dim daU As New SqlCommandBuilder(da)

            da.Update(rstData)
        End Using
    End Using


End Sub

Sub GridToTable()
    ' send all data from gv to local table

    For Each gvRow As GridViewRow In GridView1.Rows

        Dim pkID As Integer = GridView1.DataKeys(gvRow.RowIndex).Item("ID")
        Dim OneRow As DataRow = rstData.Select("ID = " & pkID).FirstOrDefault

        OneRow("FirstName") = CType(gvRow.FindControl("txtFirst"), TextBox).Text
        OneRow("LastName") = CType(gvRow.FindControl("txtLast"), TextBox).Text
        OneRow("HotelName") = CType(gvRow.FindControl("txtHotel"), TextBox).Text
        OneRow("Description") = CType(gvRow.FindControl("txtDescription"), TextBox).Text
        OneRow("Active") = CType(gvRow.FindControl("chkActive"), CheckBox).Checked

    Next

End Sub

所以在上面,我们发送了所有的编辑,所有的添加(如果你有或添加了一个删除按钮到每一行,那么即使是删除也会用上面简单的几行代码发送回数据库。作为注意,这是可能的,因为我们保留了驱动 GV 的 rstData。

真的很好吗?那么,30 多年来,地球上每个使用过 Excel 或使用过任何会计系统或任何其他计算机软件的用户?他们可以在那个网格中跳来跳去,做出改变。然后用一个简单的保存按钮将整个 she-bang 发送回数据库。