在 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 发送回数据库。
我有一个标准的 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 发送回数据库。