我使用 Grid View 創建了一個搜索功能,該程式讀取用戶輸入并根據它回傳與資料庫匹配的資料,但是它回傳整行,其中包括我不想顯示的 2 個 ID 列. 聽起來很簡單,但我似乎找不到任何關于如何做到這一點的教程。
另外,第二列IdCargo(IdProfession,英文),我想翻譯這些資料,例如,如果應該出現特定的 ID,我想改為顯示所述員工的職業。我還想顯示帶有“Cargo”名稱而不是“IdCargo”的列,我想顯示“Carga Horaria”而不是“CargaHoraria”。
如果有人知道使用 GridViews 和 SQL 的任何型別的指南或教程,那對未來的研究也將非常有幫助。

uj5u.com熱心網友回復:
偉大的。好的,我們不必擔心搜索部分 - 我假設您輸入一些搜索,帶引數,結果是一個資料表。
現在,我強烈建議您考慮使用串列視圖代替網格視圖。
至于控制哪些列?好吧,您可以對每一列進行模板化。(這就是為什么我建議使用串列視圖 - 它的標記較少)。
但是,我沒有太多的列——所以 GV 是“好的”,但如果你想要更多的列、更多的自定義布局——那么 LV 的標記就會更少。
LV 的另一個非常大的優勢是,您可以讓它為您撰寫標記。
不管怎樣,好吧,這就是我們的GV。
非常重要:我們為每一行(“ID”)都有一個 PK 主鍵。我們當然不想顯示或顯示該 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 轉換為組合框(下拉串列)。和 Near most/all 組合框一樣,我們將存盤酒店的 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 行的 CURRENT 選擇。
為此,我們將使用 GV 行資料系結事件。
因此,我們填寫組合的代碼將如下所示:
So we have this code:
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
so, now our results are this:

Ok, so that takes care of one of your questions/issues.
Next up is to edit - and this is REALLY cool, and REALLY easy.
Ok, if you look close, I "hide" the borders for the text boxes, but you find now that you can tab around quite much like excel. And a nice free-bee is that when text boxes have focus, they show!!
So lets drop in our button below the grid to save edits. It looks like this when I tab around:

Quite much like magic - you can now tab around - almost like Excel. And you can choose combo box value.
And in above, we dropped in a simple button below the GV like this:
</asp:GridView>
<asp:Button ID="cmdSave" runat="server" Text="Save Edits" CssClass="btn" />
Ok, so now the save data button.
We will write one helper routine. There is a BOATLOAD of reasons to split this code into two routines. So the first routine?
It will send the grid values BACK to our table. If you look close, I persisted the GV table data source as rstData.
So this routine sends grid back to table.
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
Ok, so now all we have to do is send the rstData table (and get this: this will handle NEW rows, or edits!!!!).
so, now our save button code looks like this:
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
So note how we send the WHOLE grid back to the database, and all changes in ONE shot.
Last but not least:
I used a helper routine to get a data table (became REAL fast typing that kind of code over and over, so I have this and I made it global to the whole application:
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
NOTE very carefull, I also STUFF the sql statement into the rst.Table name. Table name not really used, but now since I persisted the SQL for that table?
Then in fact this line
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * from People where ID = 0", conn)
becomes:
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(rstData.TableName, conn)
這意味著,如果/當我說要在頁面上編輯子母版或多個資料表時?我使用一個資料集(一組表),并且有一個程式可以一次性將所有表和所有編輯發送回資料庫。我們沒有更多的資料表要編輯,但這解釋了為什么我將 SQL 陳述句推入資料表“表”名稱中,因為如您所見,我們甚至不必重新鍵入使用的sql。
注意僅供參考:我使用的那個 sql 陳述句:
SELECT * from People WHERE ID = 0
不是 o 型。我用它來允許 sqlCommandBuilder 為我完成連接和創建 sql 插入和更新蒸汽的所有骯臟作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/367849.html
下一篇:WebApi忽略路由屬性
