這個很簡單。asp:GridView 會自動在每一列的左側添加一個編輯超鏈接,如下所示:

這很好,因為無論如何我都需要那個功能。但是,我已經做到了,因此單擊“編輯”超鏈接會彈出一個新面板,允許用戶編輯比 GridView 中顯示的更多的屬性,因此我不希望在單擊“編輯”后出現“更新”和“取消”按鈕。

我通過實作一個在 e.CommandName = "Edit" 時處理 GridView.RowCommand 的事件處理程式添加了編輯功能。我想只保留編輯超鏈接,或者可能以編程方式單擊取消,或者當用戶完成使用編輯面板時,任何會阻止更新和取消超鏈接顯示的東西。我嘗試呼叫事件處理程式并使用 e.CommandName = "Cancel" 發送引數,但這沒有用。
我愿意探索的另一個選擇是完全洗掉“編輯”按鈕并讓我的事件處理程式處理不同的事件,但我也沒有找到任何好的資源。大多數情況下,人們試圖禁用他們在某些行上手動創建的編輯按鈕。不過,我沒有創建此編輯超鏈接,我無法讓它消失。
uj5u.com熱心網友回復:
好吧,既然你彈出一個面板?然后只需轉儲整個模板和自動編輯系統。真的,為了快速和骯臟 - 那些內置的 GV 事件非常適合讓您啟動和運行。
但是,一旦你真正了解了這一切是如何運作的?盡管如此,您可以按照自己的方式撰寫純代碼,甚至可以使用 LESS 代碼和 LESS 標記,減少麻煩!!!
事實上,您甚至可以轉儲整個 GV“行”處理程式——因為它在這里并沒有真正給您帶來任何好處。
事實上,甚至更好?只需放入一個平面簡編輯按鈕 - 甚至是一個 asp.net 按鈕。你真的不需要更多的東西了!- 你經常會得到更少混亂的代碼。真的很棒嗎?好吧,您添加到 GV 的每個按鈕都有自己的單擊事件 - 它是否具有自己的按鈕單擊以及自己的按鈕單擊 - 很像您剛剛放入 GV 的任何其他控制元件或按鈕。
事實上,如果問題是如何像 Excel 一樣使用標簽和編輯 gv,我可以發布一個非常簡短、簡單的解決方案,并且沒有一個使用 GV 的內置事件。
但是,讓我們概述一下它是如何作業的,并使用“最少”的代碼。
你沒有提到你在這里使用什么樣的“對話框”(其中有很多,從 jquery.UI(我將使用),甚至來自 ajaxtoolkit 的對話框也非常好。
所以,我會說我不喜歡建議引入“再多一個”JavaScript 庫。但是,幾乎可以肯定的是,您默認安裝了 jQuery。所以,添加 jquery.UI 并不是什么大不了的事。
所以,我們的目標:
Dump the messy GV event model.
STILL use write as much as possible easy server side code.
Write and use a absolute min of JavaScript code.
現在,我將使用我在 vb.net 中撰寫的一些輔助例程。它們很短,而且易于使用。我很快就厭倦了一遍又一遍地撰寫相同的代碼:
Shuffle data from data table to some controls for edit
Shuffle data from controls back to table, and then save table to database.
然而,即使沒有上述“shuffle to/from”例程,您也可以看到,通過實際轉儲 GV 事件,這段代碼的麻煩要少得多。
好的,所以,讓我們假設一個簡單的酒店網格。在每一行上,我們都需要一個編輯按鈕。
所以,第一個簡單的部分,這里是我們的網格:
<div style="width:40%">
<asp:GridView ID="GHotels" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn" OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
A few FYI: Yes, to save time, I did use the wizards to create above. I then blow out the datasource1, and data source setting of the gv. and I removed the "ID" from display for each row. NOTE VERY careful - the PK row "id" setting is now this:
DataKeyNames="ID"
This is great feature, since it will maintain, use, and allow you to easy get the PK row id, but NOT have to expose it in the markup - less code, better to never show the PK stuff to users.
And note how I set CssClass="table". Don't worry about that, but doing so will bootstrap the GV - and it looks WAY WAY nicer. (and it also auto expands/grows to the div width size - do try this - since bootstrap is installed by default).
And now our code is this: (don't worry - I'll include all code used here).
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 cmdSQL As New SqlCommand("SELECT * FROM tblHotelsA ORDER BY HotelName")
GHotels.DataSource = MyrstP(cmdSQL)
GHotels.DataBind()
End Sub
and now we have this:

So far, really easy.
Now, it not clear what you used for editing (your popup), but we need "some kind" of popup system. So, I'll pick jquery.UI. It work rather well - far better then trying to get a bootstrap dialog to work.
So, after the GV, we need to layout make a "one row" editor. (and place it in a div). so, this looks quite nice for this purpose: (and during development, I do NOT set display:none, but once you have it looking ok, then set display:none for the div style - that hides it (jquery.ui then takes care of this).
Ok, not too much to our "edit detals div". I dropped htis right after the GV.
So, we have this:
<div id="EditRecord" runat="server" style="float:left;display: none">
<style>
.iForm label {display:inline-block;width:90px}
.iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm input[type=checkbox] {margin-right:8px}
</style>
<div style="float:left" class="iForm">
<label>HotelName</label><asp:TextBox ID="txtHotel" runat="server" f="HOtelName" width="280"></asp:TextBox> <br />
<label>First Name</label><asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox> <br />
<label>Last Name</label><asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox> <br />
<label>City</label><asp:TextBox ID="tCity" runat="server" f="City" Width="140"></asp:TextBox> <br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox> <br />
</div>
<div style="float:left;margin-left:20px" class="iForm">
<label>Description</label> <br />
<asp:TextBox ID="txtNotes" runat="server" Width="400" TextMode="MultiLine"
Height="150px" f="Description" ></asp:TextBox> <br />
<asp:CheckBox ID="chkActive" f="Active" Text=" Active" runat="server" TextAlign="Right" />
<asp:CheckBox ID="chkBalcony" f="Balcony" Text=" Has Balcony" runat="server" TextAlign="Right" />
</div>
<div style="clear:both"></div>
<button id="cmdSave" runat="server" class="btn" onserverclick="cmdSave_ServerClick" >
<span aria-hidden="true" class="glyphicon glyphicon-floppy-saved"> Save</span>
</button>
<button id="cmdCancel" runat="server" class="btn" style="margin-left:15px">
<span aria-hidden="true" class="glyphicon glyphicon-arrow-left"> Back/Cancel</span>
</button>
<button id="cmdDelete" runat="server" class="btn" style="margin-left:15px">
<span aria-hidden="true" class="glyphicon glyphicon-trash"> Delete</span>
</button>
</div>
And now our ONE bit of JavaScript - but this is ALL we have to write:
Drop this right after the above div:
<script>
function PopEdit() {
var myDialog = $("#EditRecord");
myDialog.dialog({
title: "Edit Hotel Information",
modal: true,
width: 860,
appendTo: "form"
});
}
</script>
Ok, that is quite much it.
Now, we have that row button click. As noted, this is just a plane jane asp.net button, or whatever you like.
That button in the GV was this:
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn" OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
And the code for this button:
Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
Dim pkID = GHotels.DataKeys(gRow.RowIndex).Item("ID")
Dim cmdSQL As New SqlCommand("SELECT * from tblHotelsA where ID = @ID")
cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = pkID
Dim rstData As DataTable = MyrstP(cmdSQL)
Call fLoader(Me.EditRecord, rstData.Rows(0))
ViewState("rstData") = rstData
ClientScript.RegisterStartupScript(Page.GetType(), "PopEditKey", "PopEdit()", True)
End Sub
Not a lot of code. We simple load up our "div", and then pop it with that one lone jquery.UI bit of code.
And the result is Now this:

Ok, so now we need the save button code. That is this:
Protected Sub cmdSave_ServerClick(sender As Object, e As EventArgs)
Dim rstData As DataTable = ViewState("rstData")
Call fWriterW(EditRecord, rstData.Rows(0))
Call SaveTable(rstData, "tblHotelsA")
LoadGrid()
End Sub
And the cancel/back button? Well as we know ANY post-back will collopse the dialog, so it actually does not need much code. And if you wish, I can post the code for the delete button (and we probably should provide a nice looking "confirm" delete prompt - and we can use a jQuery.Ui dialog for that - but again, use 90% server side clean vb code for the delete button.
Ok, so now the helper routines I used for above.
I have 3
MyRstP - this just accepts a sql command - retruns a table.
Public Function MyrstP(sqlCmd As SqlCommand) As DataTable
Dim rstData As New DataTable
Using sqlCmd
Using conn = New SqlConnection(My.Settings.TEST4)
conn.Open()
sqlCmd.Connection = conn
rstData.Load(sqlCmd.ExecuteReader)
End Using
End Using
Return rstData
End Function
above just saves the hassle of "over and over" having to write query code.
Then we have a routine called "fLoader". Once again, it became OH so tiring to write code over and over that just takes a data row, and shoves it out to controls on the form. So, for each control in a "div", I just make up my own "tag". I use f="data base column name goes here"
So, inside of a given div, then you see this for hotel name:
<label>HotelName</label><asp:TextBox ID="txtHotel" runat="server" f="HotelName" width="280"></asp:TextBox> <br />
<label>First Name</label><asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox> <br />
So, for each control, I kind of cooked up my own binding - saves you have to write that code over and over.
So, floader looks like this (I just added a module1 to mycode). and thus all forms and routines can use this code. All it does is take the rstData (row(0), and move the database columns to the controls that have a tag f="column name". It is a bit of code, but after having written it, it sure makes shoving data out to controls rather easy.
Public Sub fLoader(F As HtmlGenericControl, rst As DataRow)
For Each c As System.Web.UI.Control In F.Controls
Select Case c.GetType
Case GetType(TextBox)
Dim ctlC As TextBox = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
ctlC.Text = IIf(IsDBNull(rst(ctlC.Attributes("f"))), "", rst(ctlC.Attributes("f")))
End If
End If
Case GetType(Label)
Dim ctlC As Label = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
ctlC.Text = IIf(IsDBNull(rst(ctlC.Attributes("f"))), "", rst(ctlC.Attributes("f")))
End If
End If
Case GetType(DropDownList)
Dim ctlC As DropDownList = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
ctlC.Text = IIf(IsDBNull(rst(ctlC.Attributes("f"))), "", rst(ctlC.Attributes("f")))
End If
End If
Case GetType(CheckBox)
Dim ctlC As CheckBox = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
ctlC.Checked = rst(ctlC.Attributes("f"))
End If
End If
Case GetType(RadioButtonList)
Dim ctlC As RadioButtonList = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
ctlC.SelectedValue = rst(ctlC.Attributes("f"))
End If
End If
End Select
Next
End Sub
And then I have the reverse. Take from controls -> back into the rstData (data row, but from the datatable).
It really is the above code in "reverse" and takes values from controls and shoves then back into the rstData.
Public Sub fWriterW(f As HtmlGenericControl, rst As DataRow)
For Each c As System.Web.UI.Control In f.Controls
Select Case c.GetType
Case GetType(TextBox)
Dim ctlC As TextBox = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
rst(ctlC.Attributes("f")) = IIf(ctlC.Text = "", DBNull.Value, ctlC.Text)
End If
End If
Case GetType(Label)
Dim ctlC As Label = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
rst(ctlC.Attributes("f")) = IIf(ctlC.Text = "", DBNull.Value, ctlC.Text)
End If
End If
Case GetType(DropDownList)
Dim ctlC As DropDownList = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
rst(ctlC.Attributes("f")) = IIf(ctlC.Text = "", DBNull.Value, ctlC.Text)
End If
End If
Case GetType(CheckBox)
Dim ctlC As CheckBox = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
rst(ctlC.Attributes("f")) = ctlC.Checked
End If
End If
Case GetType(RadioButtonList)
Dim ctlC As RadioButtonList = c
If Not ctlC.Attributes("f") Is Nothing Then
If rst.Table.Columns.Contains(ctlC.Attributes("f")) Then
rst(ctlC.Attributes("f")) = ctlC.SelectedValue
End If
End If
End Select
Next
End Sub
and then one more routine - this routine just saves the database table BACK to the database. Hence you pass it the rstData, and table name.
Sub SaveTable(rstData As DataTable, strTable As String)
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("select * FROM " & strTable, conn)
Dim da As New SqlDataAdapter(cmdSQL)
Dim daU As New SqlCommandBuilder(da)
conn.Open()
da.Update(rstData)
End Using
End Using
End Sub
So, those little helper routines - I just place in a plane jane Module, and thus all my code can use it. It really nice since you really don't' mess with much sql, and NEVER have to mess with a boatload of parameters.
To be fair, I could have posted the ONE grid row button code. Note how it is a simple regular button - and does NOT use the GV events - but is a plane jane "click" event for server side code. And do look at the code close - note how it picks up the row clicked on, and also how it picked up the PK ID.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/447552.html
標籤:javascript 网 VB.net
上一篇:在ASP.NET中回傳訊息框
下一篇:如何在一個函式中呼叫多個ID?
