如何从 SQL 数据库编辑网格视图中显示的数据
Posted
技术标签:
【中文标题】如何从 SQL 数据库编辑网格视图中显示的数据【英文标题】:How to edit the data shown in a grid view from a SQL database 【发布时间】:2022-01-05 07:22:31 【问题描述】:我使用网格视图创建了一个搜索功能,程序读取用户输入并基于它返回与数据库匹配的数据,但是它返回整行,其中包括 2 个我没有的 ID 列想展示。听起来很简单,但我似乎找不到任何关于如何做到这一点的教程。
另外,第二列IdCargo
(IdProfession,英文),我想翻译这些数据,例如,如果应该出现特定的 ID,我想显示该员工的职业。我还想用“Cargo”名称而不是“IdCargo”显示列,也想显示“Carga Horaria”而不是“CargaHoraria”。
如果有人知道任何使用 GridViews 和 SQL 的指南或教程,那对未来的研究也非常有帮助。
【问题讨论】:
【参考方案1】:太好了。好的,我们不必太担心搜索部分——我假设你输入了一些搜索,带有参数,结果是一个数据表。
现在,我强烈建议您考虑使用列表视图代替网格视图。
至于控制哪些列?好吧,您可以对每一列进行模板化。 (这就是为什么我建议使用列表视图 - 它的标记更少)。
但是,我没有太多的列 - 所以 GV 是“好的”,但是如果你想要更多的列,更多的自定义布局 - 那么 LV 将是 LESS 标记。
LV 的另一个真正大的优势是你可以让它为你编写标记。
不管怎样,好吧,这是我们的 GV。
非常重要: 每行都有一个 PK 主键(“ID”)。我们当然不想显示或显示那个 PK ID,但众所周知,PK 是任何数据系统的命脉。因此,GV 中有一个非常酷的功能——称为 DataKeys。它允许您使用/拥有/播放 PK 行 ID,但您不必在 GV 中公开或显示它。 (所以不仅从 UI 的角度来看很好,从安全的角度来看也非常好)。
所以,假设我们有这个 GV 布局:
<div style="width:40%;padding:25px">
<style> .borderhide input border:none</style>
<asp:GridView ID="GVPeople" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" cssclass="table borderhide">
<Columns>
<asp:TemplateField HeaderText="First Name">
<ItemTemplate>
<asp:TextBox ID="FirstName" runat="server" Text='<%# Eval("FirstName") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Last Name">
<ItemTemplate>
<asp:TextBox ID="LastName" runat="server" Text='<%# Eval("LastName") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:TextBox ID="City" runat="server" Text='<%# Eval("City") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Active" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="Active" runat="server"
Checked='<%# Eval("Active") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Hotel ID">
<ItemTemplate>
<asp:TextBox ID="Hotel_ID" runat="server" Text='<%# Eval("Hotel_ID") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
我们会通过数据感受这个 GV - 存在更多列 - 但我们不在乎。
所以,到目前为止我的代码是这样的:
Dim rstData As New DataTable
Dim rstHotels As New DataTable ' for combo box
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
ViewState("rstData") = rstData
Else
rstData = ViewState("rstData")
End If
End Sub
Sub LoadGrid()
rstHotels = MyRst("SELECT ID, HotelName from tblHotels ORDER BY HotelName")
rstData = MyRst("SELECT * from People Order by FirstName")
GVPeople.DataSource = rstData
GVPeople.DataBind()
End Sub
所以现在我们有了这个:
好的,所以您的问题之一是我们显然不想显示 Hotel_id,而是想将其翻译成描述。当然,如果我们要允许编辑,那么让我们将 Hotel_ID 转换为组合框(下拉列表)。和大多数/所有组合框一样,我们将存储酒店的 PK id,但当然显示酒店名称以方便使用。
所以,代替hotel_id,我们将标记更改为:
<asp:TemplateField HeaderText="Hotel ID">
<ItemTemplate>
<asp:DropDownList ID="cboHotel" runat="server"
DataTextField="HotelName"
DataValueField="ID">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
好的,现在我们必须填充 + 设置组合框。我们有两个任务:
用数据源填充组合框
将组合框设置为每个 gv 行的当前选择。
为此,我们将使用 GV 行数据绑定事件。
所以,我们填写组合的代码如下所示:
所以我们有这个代码:
Protected Sub GVPeople_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GVPeople.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
' get full row of data bind - all columns
Dim gData As DataRowView = e.Row.DataItem ' NOT A GRID VIEW ROW!!!!!
' get combo box
Dim cboHotels As DropDownList = e.Row.FindControl("cboHotel")
' setup cbo data source
cboHotels.DataSource = rstHotels
cboHotels.DataBind()
cboHotels.Items.Insert(0, New ListItem("", "")) ' add blank (no choice)
If IsDBNull(gData("Hotel_id")) = False Then
cboHotels.SelectedValue = gData("Hotel_ID").ToString
End If
End If
End Sub
所以,现在我们的结果是这样的:
好的,这样就可以解决您的一个问题/问题。
接下来是编辑 - 这真的很酷,也很简单。
好的,如果您仔细观察,我会“隐藏”文本框的边框,但您现在发现您可以像 Excel 一样使用 Tab 键。一个不错的免费蜜蜂是当文本框有焦点时,它们会显示!!
因此,让我们将我们的按钮放在网格下方以保存编辑。当我点击时它看起来像这样:
很像魔术 - 您现在可以使用标签 - 几乎就像 Excel。并且您可以选择组合框的值。
在上面,我们在 GV 下方放置了一个简单的按钮,如下所示:
</asp:GridView>
<asp:Button ID="cmdSave" runat="server" Text="Save Edits" CssClass="btn" />
好的,现在是保存数据按钮。
我们将编写一个辅助例程。将此代码拆分为两个例程的原因有很多。那么第一个套路呢?
它将网格值发送回我们的表。如果仔细观察,我会将 GV 表数据源持久化为 rstData。
所以这个例程将网格发送回表格。
Sub GridToTable()
' pull GV rows back to table.
For Each gRow As GridViewRow In GVPeople.Rows
' Get database PK value
Dim PK As Integer = GVPeople.DataKeys(gRow.RowIndex).Item("ID")
Dim OneDataRow As DataRow = rstData.Select("id = " & PK)(0)
OneDataRow.Item("FirstName") = CType(gRow.FindControl("FirstName"), TextBox).Text
OneDataRow.Item("LastName") = CType(gRow.FindControl("LastName"), TextBox).Text
OneDataRow.Item("City") = CType(gRow.FindControl("City"), TextBox).Text
OneDataRow.Item("Active") = CType(gRow.FindControl("Active"), CheckBox).Checked
' combo box
Dim cboHotel As DropDownList = gRow.FindControl("cboHotel")
If cboHotel.Text = "" Then
OneDataRow("Hotel_ID") = DBNull.Value
Else
OneDataRow("Hotel_ID") = cboHotel.SelectedItem.Value
End If
Next
End Sub
好的,所以现在我们要做的就是发送 rstData 表(并得到这个:这将处理新行或编辑!!!!)。
所以,现在我们的保存按钮代码如下所示:
Protected Sub cmdSave_Click(sender As Object, e As EventArgs) Handles cmdSave.Click
GridToTable()
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * from People where ID = 0", conn)
Dim da As New SqlDataAdapter(cmdSQL)
Dim daC As New SqlCommandBuilder(da)
conn.Open()
da.Update(rstData)
End Using
End Using
End Sub
所以请注意我们如何将整个网格发送回数据库,以及一次拍摄中的所有更改。
最后但并非最不重要的一点:
我使用了一个辅助例程来获取一个数据表(一遍又一遍地键入那种代码变得非常快速,所以我有了这个并将其设置为对整个应用程序都是全局的:
Public Function MyRst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
rstData.TableName = strSQL
End Using
End Using
Return rstData
End Function
注意非常小心,我还将 sql 语句填充到 rst.Table 名称中。表名并没有真正使用,但现在因为我为该表保留了 SQL?
那么其实就是这一行
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * from People where ID = 0", conn)
变成:
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(rstData.TableName, conn)
这意味着如果/当我说要在页面上编辑子母版或多个数据表时?我使用一个数据集(表的集合),并有一个 routien 一次性将所有表和所有编辑发送回数据库。我们没有超过一个数据表要编辑,但这解释了为什么我将 SQL 语句推入数据表“表”名称,因为如您所见,我们甚至不必重新输入使用的sql。
请注意: 我使用的那个sql语句:
SELECT * from People WHERE ID = 0
不是类型-o。我用它来让 sqlCommandBuilder 为我完成所有繁琐的连接和创建 sql 插入和更新流的工作。
【讨论】:
没有比这更复杂的gridview了,它是一个非常基础的学校网站,而且我喜欢gridview看起来更好。此外,我最终找到了一篇关于网格视图的文章,因此我设法更改了列的名称,唯一我还没有弄清楚的是如何将 ID“翻译”成它们所代表的内容 好吧,看看我的编辑 - 这是星期六 - 吃披萨 - 但我将发布最后一点和小代码,以展示我们如何使用简单 + 简单的代码发回网格编辑。所以在 15 分钟左右,我会回来完成下一段代码。但是发布的代码显示了我如何将值转换为组合框 另外,请随时询问 c# 代码 - 对我来说没什么区别(但由于 vb 提供了大量的自动转换,VB 代码的工作量较小)。 好了,看最后一部分再更新。请注意,代码非常简单,只需一次将整个编辑表发送回数据库。以上是关于如何从 SQL 数据库编辑网格视图中显示的数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在可缩放滚动视图中绘制可点击的网格对象,从远程 json 数据中获取数据?