提问人:Ian Burton 提问时间:11/4/2022 最后编辑:Joel CoehoornIan Burton 更新时间:11/5/2022 访问量:69
在 VB 4.8 中编写网页。GridView 具有参数,这些参数指向 DetailsView 中的新数据字段
Writing a WebPage in VB 4.8. A GridView has parameters, which outlet to new Data Fields in a DetailsView
问:
网页是为 Sales 设置的,我需要重新组织我得到的 ID 索引(在 GridView 中) 我选择了一个使用脚本化 DataTable 来填充 DetailsView 的过程。
Sub SortOrder_Item(ByVal Sender As Object, ByVal e As GridViewCommandEventArgs) Handles SortOrder.RowCommand
Dim workTable As New System.Data.DataTable
Dim DTabRow As System.Data.DataRow = workTable.NewRow
Dim index As Integer = Convert.ToInt32(e.CommandArgument)
Dim Din As GridViewRow = SortOrder.Rows(index)
if e.CommandName = "Add" Then
Dim workCol As System.Data.DataColumn = workTable.Columns.Add("ID", Type.GetType("System.Int32"))
workCol.AllowDBNull = false
workCol.Unique = false
Dim _Item_Name As String = Server.HTMLDecode(Din.Cells(1).Text)
Dim _Curr_Price As Int32 = Server.HTMLDecode(Din.Cells(4).Text)
Dim _REFNo As String = Server.HTMLDecode(Din.Cells(5).Text)
Dim Dout As Int32 = index +1
workCol = New System.Data.DataColumn()
workCol.DataType = System.Type.GetType("System.String")
workCol.AllowDBNull = True
workCol.Caption = ""
workCol.ColumnName = "ItemName" & Dout
workCol.DefaultValue = ""
workTable.Columns.Add(workCol)
workCol = New System.Data.DataColumn()
workCol.DataType = System.Type.GetType("System.Double")
workCol.AllowDBNull = True
workCol.Caption = ""
workCol.ColumnName = "Curr_Price" & Dout
workCol.DefaultValue = 0
workTable.Columns.Add(workCol)
workCol = New System.Data.DataColumn()
workCol.DataType = System.Type.GetType("System.String")
workCol.AllowDBNull = True
workCol.Caption = ""
workCol.ColumnName = "REFNo" & Dout
workCol.DefaultValue = ""
workTable.Columns.Add(workCol)
workCol = New System.Data.DataColumn()
DTabRow("ID") = Dout
DTabRow("ItemName" & Dout) = _Item_Name
DTabRow("Curr_Price" & Dout) = _Curr_Price
DTabRow("REFNo" & Dout) = _REFNo
workTable.Rows.Add(DTabRow)
DetailInsert.DataSource = workTable
DetailInsert.DataBind()
SortOrder.Enabled = False
Go_NET.Visible = True
else
Go_NET.Visible = False
end if
End Sub
Sub CustomerDetailsView_ItemUpdating(ByVal sender As Object, ByVal e As DetailsViewUpdateEventArgs)
End Sub
Sub CustomerDetailsView_ModeChanging(ByVal sender As Object, ByVal e As DetailsViewModeEventArgs)
If e.CancelingEdit Then
' The user canceled the update operation.
' Clear the error message label.
MesX1.Text = ""
End If
End Sub
因此,“编辑命令”不起作用,并且不会显示(更新/取消)控件。 如果我尝试直接将 DataSourceID 分配给我的 DetailsView 提交表单,我确信它可以工作,但整个数据库需要组织其索引。
答:
哎呀,你填写了 GV,那么为什么不直接获取该行的 pk ID,然后从数据库中重新提取那一行呢?
出于所有实际目的,它肯定不会真正增加服务器负载以重新拉取该记录。但是,虽然这不是性能问题,但它肯定会为您节省大量手动编码。
因此,我建议您不要尝试“手动编码”从 GV 创建一行。你只需要编写所有这些代码,但是如果你添加或更改列,你就会立即回到手工编码的一行数据。更糟糕的是,这样的代码真的不能被重用到其他页面。
我建议您简单地重新提取数据并获得一个漂亮的工作行。
随着时间的推移,我建议您构建一个“帮助程序”例程,该例程“自动”将一行中的列放入窗体上的控件中。这样一来,您就不必每次都手动编写控件加载代码。
然后编写一个例程来执行相反的操作(将控件中的值取回数据行)。然后再有一个例程将该行写出到数据库中。
有了这 3 个简单的例程,您现在可以将该代码用于所有表单和所有工作(而不是一遍又一遍地重写相当于相同代码的内容)。
你“可以”使用详细信息的视图,但你仍然必须输入 eval(“some column name”)。因此,不妨在 vb 中输入该代码 - 它的工作量大致相同。
因此,我建议采用以下方法:
我们的网格视图,并放入平面简常规编辑按钮(不要打扰 GridView 事件模型 - 它对于您开始使用自定义代码的非常即时的编辑来说并不是那么好)。
如前所述,详细信息视图也无济于事。 (因为我们不尝试使用内置向导,而且它们不是那么灵活)。
所以,我们的网格视图:
<div id="MyGridArea" runat="server">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID"
CssClass="table table-hover" Width="60em" GridLines="None"
ShowHeaderWhenEmpty="true">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn myshadow"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
请注意,我们该网格中既不公开也不包含 pk“ID”。我们设置/使用数据键设置(一个非常好的功能,从那时起我们不必尝试“隐藏”pk行,更好的是它是安全的 - 并且100%为我们管理服务器端)。
好的,现在我们加载网格的代码可以是这样的:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName"
GridView1.DataSource = Myrst(strSQL)
GridView1.DataBind()
End Sub
我们现在有/看到这个:
好的,现在是我们的编辑按钮。
该标记是这样的:
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn myshadow"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
但请注意上面非常接近。请注意单击事件!!
但是,我们不能只双击该按钮来创建点击事件,因为它嵌套在 GV 中。那么这个巨大的好提示?
在标记中添加单击事件,然后键入
OnClick=
点击“=”的那一刻,然后注意关闭,你会看到一个弹出窗口来添加点击事件,如下所示:
因此,我们选择创建新事件。似乎没有发生太多事情,我们的按钮标记变成了这样:
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn myshadow"
OnClick="cmdEdit_Click" />
现在,如果我们切换到代码隐藏,我们会为该按钮单击一个按钮 - 但一个在 GV 内部。
因此,我们的按钮需要:
Get the current row id, and the row PK for the database row
We then transfer that data to our "div area", and then hide the GV,
display the "edit div".
以上是“不错的”,因为现在我们再次编写平面简简单标记,我们的取消、保存甚至删除按钮也是平面简代码。
因此,现在我们唯一需要的部分是我们的“编辑 div”区域。如前所述,我在这里没有看到太多使用详细信息视图的方式。您可以使用详细信息视图,但我认为它根本没有多大帮助。
好的,所以我们的编辑 div 如下所示:
(只需在“div”中用控件、复选框等平面简标记即可编辑一行)。
<div id="EditRecord" runat="server" style="float: left; display: none" >
<br />
<div style="float: left" class="iForm">
<label>HotelName</label>
<asp:TextBox ID="txtHotel" runat="server" Width="280">
</asp:TextBox>
<br />
<label>First Name</label>
<asp:TextBox ID="tFN" runat="server" Width="140"></asp:TextBox>
<br />
<label>Last Name</label>
<asp:TextBox ID="tLN" runat="server" Width="140"></asp:TextBox>
<br />
<label>City</label>
<asp:TextBox ID="tCity" runat="server" Width="140"></asp:TextBox>
<br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" Width="75"></asp:TextBox>
</div>
<div style="float: left; margin-left: 20px" class="iForm">
<div style="float: left">
<label>Description</label>
<br />
<asp:TextBox ID="txtNotes" runat="server" Width="260px" TextMode="MultiLine"
Height="100px" ></asp:TextBox>
</div>
<div style="float: left; margin-left: 14px">
<label>Hotel Options</label>
<br />
<asp:CheckBox ID="chkSmoking" runat="server" Text="Smoking" />
<br />
<asp:CheckBox ID="chkBalcony" runat="server" Text="Balcony" />
<br />
<asp:CheckBox ID="chkBags" runat="server" Text="Has Baggage" />
<br />
</div>
<div style="clear: both">
</div>
<asp:CheckBox ID="chkActive" Text=" Active"
runat="server" TextAlign="Right" Width="171px" />
</div>
<div style="clear: both"></div>
<hr />
<button id="cmdSave" runat="server" class="btn myshadow" type="button"
onserverclick="cmdSave_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-floppy-saved">Save</span>
</button>
<button id="cmdCancel" runat="server" class="btn myshadow" style="margin-left: 15px"
type="button"
onserverclick="cmdCancel_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-arrow-left">Back/Cancel</span>
</button>
<button id="cmdDelete" runat="server" class="btn myshadow" style="margin-left: 15px"
type="button"
onserverclick="cmdDelete_ServerClick"
onclick="if (!confirm('Delete this record?')) {return false};">
<span aria-hidden="true" class="glyphicon glyphicon-trash">Delete</span>
</button>
<br />
<br />
</div>
</div>
仅供参考:
我在上面使用了html“按钮”。我本可以使用飞机简 asp.net 按钮,但我想要看起来很可爱的引导图标。我应该指出,在 bootstrap 4 之后,他们删除了 bootstap 图标的包含,但如果您愿意,如果您在使用 html“按钮”时遇到任何问题,请为这 3 个按钮使用 plane jane asp.net 按钮。我确实为这些按钮使用了 plane jane vb 代码,并注意我如何使用 onserverclick - 只是标记中的语法略有不同,但隐藏代码实际上与典型页面上的任何按钮单击代码相同。
好的,现在我们需要编辑按钮代码。
因此,这就是我们现在必须输入这些控件的地方。(如前所述,对于将来,我们可以编写一个例程,为任何标记一遍又一遍地执行此操作,但现在,婴儿步骤,只是一些婴儿步骤)。
因此,我们在编辑按钮上有此代码。
Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
Debug.Print("Row index click = " & gRow.RowIndex)
' get data base key
Dim intPK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
Dim strSQL As String = "SELECT * FROM tblHotelsA WHERE ID = " & intPK
Dim rstData As DataTable = Myrst(strSQL)
' load up our edit div area
With rstData.Rows(0)
txtHotel.Text = .Item("HotelName")
tFN.Text = .Item("FirstName")
tLN.Text = .Item("LastName")
tCity.Text = .Item("City")
tProvince.Text = .Item("Province")
txtNotes.Text = .Item("Description")
chkActive.Checked = .Item("Active")
chkBalcony.Checked = .Item("Balcony")
chkSmoking.Checked = .Item("Smoking")
End With
ViewState("PK") = intPK ' same our PK for later
ShowGrid(False) ' hide GV, show edit area
End Sub
所以,真的,在标记中加入一堆 eval(“列名”),或者按照上面的顺序在文本框中输入 = 你付出的努力大致相同。
所以,实际上,现在我们只需要一个保存按钮来将数据写回表中。
该代码实际上与编辑按钮加载代码相反。
因此,此代码可以解决问题:
Protected Sub cmdSave_ServerClick(sender As Object, e As EventArgs)
Dim intPK As Integer = ViewState("PK")
Dim strSQL As String = "SELECT * FROM tblHotelsA WHERE ID = " & intPK
Using conn = New SqlConnection(My.Settings.TEST4)
Using cmdSQL = New SqlCommand(strSQL, conn)
conn.Open()
Dim da As New SqlDataAdapter(cmdSQL)
Dim daU As New SqlCommandBuilder(da)
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
With rstData.Rows(0)
.Item("HotelName") = txtHotel.Text
.Item("FirstName") = tFN.Text
.Item("LastName") = tLN.Text
.Item("City") = tCity.Text
.Item("Province") = tProvince.Text
.Item("Description") = txtNotes.Text
.Item("Active") = chkActive.Checked
.Item("Balcony") = chkBalcony.Checked
.Item("Smoking") = chkSmoking.Checked
End With
da.Update(rstData)
End Using
End Using
LoadGrid() ' refrsh grid to show any new edits
ShowGrid(True)
End Sub
所以,这在很大程度上产生了这样的效果:
所以,它不是很多代码,但我认为更重要的是所有的代码都是相当平面的简 - 没什么花哨的。
我使用的另一个“辅助例程”就是这个,它只是为给定的 SQL 查询返回一个表:
Public Function Myrst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using mycon As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, mycon)
mycon.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
仔细记下我如何使用简单的按钮单击来获取当前的 gv 行索引和 PK。该代码适用于转发器、列表视图、网格视图等,它允许您省去内置的网格/列表视图/转发器事件,并使用简单的按钮单击。
评论