導(dǎo)言
在前面一些教程中,我們已經(jīng)看到如何使用應(yīng)用程序框架,ObjectDataSource,以及那些提供增、改、刪功能的數(shù)據(jù)Web控件。在我們已經(jīng)實現(xiàn)的刪除數(shù)據(jù)的界面中,包含一個刪除按鈕,當(dāng)點擊它的時候,會導(dǎo)致數(shù)據(jù)回傳以及調(diào)用ObjectDataSource的Delete()方法。然后Delete()方法會調(diào)用對應(yīng)業(yè)務(wù)邏輯層中的方法,再進入數(shù)據(jù)訪問層,直至調(diào)用最終操作數(shù)據(jù)庫的DELETE語句。
雖然這個界面已經(jīng)能夠讓用戶通過GridView,DetailsView,或者FormView控件來刪除記錄,但是在用戶點擊刪除按鈕的時候,它缺少一些提示信息。如果用戶本想點擊編輯按鈕,但是不小心點擊了刪除按鈕,那么原本會更新的記錄將會被刪除。為了避免此類事情發(fā)生,在這篇教程里面,我們將為點擊刪除按鈕的時候,添加一個能在客戶端顯示提醒的窗口。
JavaScript的confirm(string)方法將在一個模式窗口中顯示那些作為string參數(shù)傳進來的文本,這個窗口將會顯示兩個按鈕-確定(OK)和取消(Cancel)。(見圖1)confirm(string)方法將根據(jù)點擊不同的按鈕來返回一個布爾類型值。(返回true,如果點擊了確定(OK),返回false如果點擊了取消(Cancel))
圖1:JavaScript的confirm(string)方法顯示一個模式的,客戶端的窗口
在一個表單的提交過程中,如果從客戶端的事件處理器返回一個false值,那么這個表單將取消提交。使用這種特性,我們可以在這個刪除按鈕的客戶端事件處理器 onClick中,調(diào)用confirm(“你確定要刪除這個產(chǎn)品嗎?”),讓它返回一個布爾值。如果用戶點擊了取消,confirm(string)將返回false,因此會取消表單的提交。在沒有回傳的前提下,這個已經(jīng)點擊了刪除按鈕的產(chǎn)品并沒有被刪除。相反,如果在確認窗口中用戶點擊了確定,回傳將會繼續(xù)而且這個產(chǎn)品將會被刪除。參考 使用JavaScript的confirm()方法控制表單提交 來獲取這方面的更多信息。
在添加這些有用的客戶端腳本時候,使用模版和使用一個CommandField相比,將會有一些細微的差別。因此,在這篇教程中,我們將同時考察FormView和GridView的例子。
注意:正如這篇教程中討論到的,使用客戶端確認技術(shù)時候,我們假設(shè)用戶的瀏覽器支持JavaScript并且已經(jīng)啟用了JavaScript支持。如果這其中的任何一個假設(shè)不能滿足,那么點擊刪除按鈕的時候?qū)⒓催M行回傳而不會顯示一個確認窗口。
第一步:新建一個支持刪除的FormView
首先在EditInsertDelete目錄下面,創(chuàng)建ConfirmationOnDelete.aspx頁面,并添加一個FormView控件,然后給這個控件綁定一個ObjectDataSource,這個數(shù)據(jù)源控件將從ProductsBLL類的GetProducts()方法獲取產(chǎn)品信息。同時給它的Delete()方法綁定指向ProductsBLL類的DeleteProduct(productID)方法。確保INSERT和UPDATE標(biāo)簽的下拉框中為(None)。最后,在FormView的屬性窗口中勾上Enable Paging多選框。
通過這些步驟,創(chuàng)建了一個以下語句聲明的ObjectDataSource:
asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DeleteMethod="DeleteProduct" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
DeleteParameters>
asp:Parameter Name="productID" Type="Int32" />
/DeleteParameters>
/asp:ObjectDataSource>
因為在我們前面的例子中沒有使用到optimistic concurrency,可以把OldValuesParameterFormatString屬性刪掉。
因為這個FormView已經(jīng)被綁定到一個僅僅支持刪除的ObjectDataSource控件,在ItemTemplate中我們只要提供刪除按鈕,而不需要新建和更新按鈕。而在FormView的聲明標(biāo)記中,可以刪掉我們不再需要的EditItemTemplate以及InsertItemTemplate。稍微花點時間定制一下ItemTemplate以便只顯示一組產(chǎn)品屬性。我已經(jīng)定制好了,用h3>樣式顯示產(chǎn)品的名字作為標(biāo)題,接下來是供應(yīng)商和分類的名字(以及刪除按鈕)。
asp:FormView ID="FormView1" AllowPaging="True" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" runat="server">
ItemTemplate>
h3>i>%# Eval("ProductName") %>/i>/h3>
b>Category:/b>
asp:Label ID="CategoryNameLabel" runat="server"
Text='%# Eval("CategoryName") %>'>
/asp:Label>br />
b>Supplier:/b>
asp:Label ID="SupplierNameLabel" runat="server"
Text='%# Eval("SupplierName") %>'>
/asp:Label>br />
asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete">
/asp:LinkButton>
/ItemTemplate>
/asp:FormView>
做了這些變化之后,我們已經(jīng)有了一個功能完善的頁面,可以允許用戶顯示每個產(chǎn)品,以及通過簡單地點擊按鈕來刪除某個產(chǎn)品。圖2顯示了在瀏覽器中訪問我們上面所完成的例子的截圖。
圖2:FormView控件顯示一個產(chǎn)品
第二步:在刪除按鈕的客戶端onclick事件中調(diào)用confirm(string)方法
在創(chuàng)建FormView之后,最后的步驟是配置這個刪除按鈕,使得用戶點擊它的時候,JavaScript的confirm(string)方法會被調(diào)用??梢酝ㄟ^使用OnClientClick這個屬性來為Button,LinkButton,ImageButton的客戶端onclick事件添加客戶端腳本,這個屬性是ASP.NET 2.0新引入的。因為我們想讓confirm(string)方法有返回值,可以簡單地設(shè)置屬性值為:return confirm(‘你確定要刪除這個產(chǎn)品嗎?')。
修改之后這個刪除按鈕的聲明語法應(yīng)該如下所述:3給出了這個提示操作的截圖。點擊這個刪除按鈕激活確認窗口的顯示。如果用戶選擇取消,回傳將被取消,產(chǎn)品也不會被刪除。相反,用戶選擇確定,回傳繼續(xù),ObjectDataSource的Delete()方法被調(diào)用,最后數(shù)據(jù)庫中相應(yīng)的記錄也會被刪除。
asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete"
OnClientClick="return confirm('Are you certain you want to delete this product?');">
/asp:LinkButton>
僅僅只需要這么多!
注意:傳入confirm(string) JavaScript方法的字符串用單引號進行標(biāo)記(而不是雙引號)。在JavaScript中,標(biāo)記字符串可以是單引號也可以是雙引號。我們這里使用單引號是為了確保不影響OnClientClick這個屬性本身的雙引號標(biāo)記。
圖3:當(dāng)點擊刪除按鈕時候顯示一個確認窗口
第三步:在一個CommandField中為刪除按鈕設(shè)置OnClientClick屬性
在模板中直接使用Button,LinkButton,或者ImageButton的時候,可以直接為它的OnClientClick屬性設(shè)置確認窗口并返回confirm(string) JavaScript的返回值。然而,CommandField是在GridView或者DetailsView上內(nèi)置的一些刪除按鈕,而且它們本身不具有OnClientClick屬性可以設(shè)置聲明。相反,我們必須要在處理GridView或者DetailsView,它們適當(dāng)?shù)腄ataBound事件的代碼中,引用這個刪除按鈕,然后在那里設(shè)置它的OnClientClick屬性。
注意:當(dāng)我們在適當(dāng)?shù)腄ataBound事件處理器中設(shè)置刪除按鈕的OnClientClick屬性時候,我們已經(jīng)有權(quán)限訪問當(dāng)前綁定的數(shù)據(jù)。這意味著我們可以擴展確認信息,并包含具體記錄的詳細信息,比如,“你確定要刪除這個Chai產(chǎn)品嗎?“這些定制也可以在模板的數(shù)據(jù)綁定的語法中實現(xiàn)。
為了實踐在一個CommandField中設(shè)置刪除按鈕的OnClientClick屬性,我們在頁面上添加一個GridView。配置這個GridView使用FormView一樣的ObjectDataSource控件。同時,限制GridView的BoundFields屬性只包括產(chǎn)品名稱,分類和供應(yīng)商。最后,在GridView的屬性窗口中勾上Enable Deleting的多選框。這樣會在GridView的ColumnCollection的集合中添加一列CommandField,并且它的ShowDeleteButton屬性會設(shè)置成true。
做了這些改變后,你的GridView的聲明標(biāo)記應(yīng)該如下所示:
asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
Columns>
asp:CommandField ShowDeleteButton="True" />
asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"
SortExpression="CategoryName" />
asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
/Columns>
/asp:GridView>
這個CommandField包含一個刪除LinkButton實例,并且可以在GridView的RowDataBound事件處理器中被訪問。一旦被引用,我們就可以相應(yīng)地設(shè)置它的OnClientClick屬性。通過下面的代碼來新建一個RowDataBound事件的處理器:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// reference the Delete LinkButton
LinkButton db = (LinkButton)e.Row.Cells[0].Controls[0];
// Get information about the product bound to the row
Northwind.ProductsRow product =
(Northwind.ProductsRow) ((System.Data.DataRowView) e.Row.DataItem).Row;
db.OnClientClick = string.Format(
"return confirm('Are you certain you want to delete the {0} product?');",
product.ProductName.Replace("'", @"\'"));
}
}
這個事件處理器將在代碼中綁定數(shù)據(jù)和引用刪除按鈕的時候被調(diào)用??偟膩碚f,使用了以下模式:
ButtonType是被CommandField使用的一種按鈕類型,可以是Button,LinkButton,或者ImageButton。默認情況下,CommandField使用LinkButton,但也可以通過CommandField的ButtonType屬性來定制。CommandFieldIndex是CommandField在GridView中Columns集合中的原始索引,而controlIndex是刪除按鈕在CommandField的Controls集合中的索引。controlIndex的值由按鈕在CommandField中和其他按鈕的相對位置決定。例如,如果在CommandField中只有一個刪除按鈕,那么它的索引就是0。然而,如果在刪除按鈕前面還有一個編輯按鈕,那么索引值是2。因為在刪除按鈕前面有兩個控件,一個是編輯按鈕,另一個是LiteralControl,用來隔離編輯按鈕和刪除按鈕。
ButtonType obj = (ButtonType) e.Row.Cells[commandFieldIndex].Controls[controlIndex];
在我們的例子中,CommandField使用了LinkButton,在最左端,commandFieldIndex的值是0。因為除了刪除按鈕,沒有其他控件,所以controlIndex的值也為0。
在引用了CommandField中的刪除按鈕之后,我們接下來可以獲得GridView當(dāng)前數(shù)據(jù)列的一些產(chǎn)品信息。最后,我們?yōu)閯h除按鈕設(shè)置了OnClientClick屬性的JavaScript值,其中包含了產(chǎn)品的名稱。因為我們用單引號標(biāo)記了傳入confirm(string)的字符串參數(shù),對于產(chǎn)品的名稱我們必須要過濾可能出現(xiàn)在其中的單引號。具體來說,我們可以把產(chǎn)品名稱中含有的單引號轉(zhuǎn)義成,“/'“。
做完這些改變之后,點擊GridView中的刪除按鈕,可以顯示一個定制后的確認信息(見圖4)。如果用戶點擊彈出的確認窗口中的取消,回傳將會被取消,從而阻止了刪除操作發(fā)生。
注意:我們同樣可以在代碼中對DetailsView的CommandField使用這種技術(shù)。然而對于DetailsView,你需要為DataBound事件提供一個處理器,因為它沒有RowDataBound事件。
圖4:點擊GridView的刪除按鈕,顯示一個定制的確認信息窗口
使用TemplateFields
使用CommandField的一個缺點是必須通過索引訪問到它的按鈕,這會導(dǎo)致對象被轉(zhuǎn)換成對應(yīng)的按鈕類型(Button,LinkButton或者ImageButton)。使用“magic numbers“和硬編碼的類型會導(dǎo)致只有在運行時候才會被發(fā)現(xiàn)的錯誤。例如,如果你,或者其他開發(fā)人員,在將來某個時候為CommandFields添加了新的按鈕(比如是編輯按鈕)或者改變了ButtonType屬性,現(xiàn)有的代碼將會順利被編譯,但是當(dāng)頁面訪問時候就可能會拋出異常或者不可預(yù)料的錯誤,這些直接由你書寫的代碼和做的改變來決定。
一個二者擇一的辦法是,不使用GridView或者DetailsView的CommandFields,而是使用TemplateFields。在TemplateField中可以含有ItemTemplate,在ItemTemplate下面可以設(shè)置LinkButton或者Button,ImageButton正如CommandField中的一樣。而且這些按鈕的OnClientClick屬性是可以顯示聲明的,就像FormView中看到的,或者我們可以使用以下模式在代碼中適當(dāng)?shù)腄ataBound事件處理器中訪問,
controlID是按鈕ID的屬性值,雖然這種辦法仍然需要硬編碼類型的轉(zhuǎn)換,但是不再需要索引,可以改變界面而不再出現(xiàn)運行錯誤。
ButtonType obj = (ButtonType) e.Row.FindControl("controlID");
總結(jié)
JavaScript的confirm(stirng)方法在表單遞交過程中是一個經(jīng)常使用的技術(shù)。當(dāng)執(zhí)行的時候,這個方法會顯示一個模式的,客戶端的窗口,包含兩個按鈕,一個OK(確定)一個Cancel(取消)。如果用戶點擊了OK(確定),confirm(string)方法會返回true,否則返回false。這種功能,以及在表單遞交的事件處理器中返回false會導(dǎo)致瀏覽器取消表單提交的功能,可以用來在刪除一條記錄的時候的顯示一個確認窗口。
通過設(shè)置按鈕控件的OnClientClick屬性,可以使得這個confirm(string)方法和按鈕控件的客戶端onclick事件處理器相結(jié)合。當(dāng)在模版中使用刪除按鈕的時候-或者在一個FormView的模版中,又或者一個TemplateField在DetailsView或GridView中-正如我們在教程中看到的一樣,我們可以顯示聲明訪問它或者在代碼中訪問它。
祝編程快樂!
作者簡介
Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創(chuàng)始人,自1998年以來一直應(yīng)用 微軟Web技術(shù)。Scott是個獨立的技術(shù)咨詢顧問,培訓(xùn)師,作家,最近完成了將由Sams出版社出版的新作,24小時內(nèi)精通ASP.NET 2.0。他的聯(lián)系電郵為mitchell@4guysfromrolla.com,也可以通過他的博客http://scottonwriting.net/與他聯(lián)系。
您可能感興趣的文章:- asp.net下gridview 批量刪除的實現(xiàn)方法
- Asp.Net+XML操作基類(修改,刪除,新增,創(chuàng)建)
- asp.net GridView 刪除時彈出確認對話框(包括內(nèi)容提示)
- asp.net中g(shù)ridview的查詢、分頁、編輯更新、刪除的實例代碼
- asp.net 編輯gridview的小例子
- Asp.net的GridView控件實現(xiàn)單元格可編輯方便用戶使用
- ASP.NET MVC4入門教程(六):驗證編輯方法和編輯視圖
- 在ASP.NET 2.0中操作數(shù)據(jù)之十六:概述插入、更新和刪除數(shù)據(jù)
- 在ASP.NET 2.0中操作數(shù)據(jù)之十七:研究插入、更新和刪除的關(guān)聯(lián)事件
- 在ASP.NET 2.0中操作數(shù)據(jù)之十九:給編輯和新增界面增加驗證控件
- 在ASP.NET 2.0中操作數(shù)據(jù)之三十六:在DataList里編輯和刪除數(shù)據(jù)概述