The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

利用 ASP.NET 2.0 的 Control Adapter 架構實做「刪除」按鈕

在設計管理介面時,一定會做「刪除」功能,我想很多人都會在「刪除」按鈕加上一個 JavaScript 確認的程式,以確保使用者沒有誤觸刪除按鈕而導致資料直接被刪除。

對一個普通的按鈕來說,要加上「刪除確認」的程式是很容易的,只要在 Button 控制項的 OnClientClick 屬性加上 confirm() 函數就可以做倒刪除確認的功能:

<asp:Button ID="mDelete_Button" runat="server" Text="刪除"
    OnClientClick="if(!confirm('你確定要刪除嗎?')) return false;"  />

而對於最常用需要用到刪除功能的地方不外乎是 GridView、DetailsView 或 FormView 控制項中,如果你要在這些控制項裡增加「刪除」功能是很容易的,一般來說會有兩種作法:

第一種:新增一個 CommandField 宣告,就可以新增一個刪除的按鈕:

<asp:CommandField ButtonType="Button" ShowDeleteButton="true"
    DeleteText="刪除" HeaderText="刪除" />

但是第一種作法很不容易加上 OnClientClick 屬性,以 GridView 控制項為例,真的要替 CommandField 的刪除按鈕加上 onclick 屬性必須實做 RowDataBound 事件,並在事件中找到這個 Button 控制項 ( 如果你 CommandField 中的 ButtonType 屬性設定為 Button 的話 ),再手動加入 onclick 屬性(Attribute),這真是太麻煩了。

第二種:新增一個 TemplateField 宣告,並自己新增 Button 控制項進去,有經驗的人就知道只要將 CommandName 設定成 Delete 就可以讓這個按鈕跟使用 CommandField 的刪除功能一模一樣,其實 CommandField 輸出的控制項就是將 CommandName 設定為 Delete。如果要加上刪除確認功能,這時就不需要再寫 Code Behind 的程式了,直接在 *.aspx 頁面的刪除按鈕加上 OnClientClick 屬性就好了,就如同本篇文章最上面的那個範例一樣。

<asp:TemplateField>
    <ItemTemplate>
        <asp:Button ID="mDelete_Button" runat="server" CommandName="Delete"
Text="刪除" OnClientClick="if(!confirm('你確定要刪除嗎?')) return false;" /> </ItemTemplate> </asp:TemplateField>

不過,我今天要講的技巧更厲害,是透過 ASP.NET 2.0 的 Control Adapter 機制,直接設定「全站」所有的 Button 控制項只要遇到 CommandName 為 Delete 的,就自動加上 OnClickClick 屬性進行刪除確認的功能。

首先,你必須在你的網站專案加上 App_Browsers 目錄,並新增一個 ControlAdapters.browser 檔案 (檔名可以改,副檔名不能改),並輸入以下內容:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.WebControls.Button" adapterType="ButtonAdapter" />
      <adapter controlType="System.Web.UI.WebControls.LinkButton" adapterType="ButtonAdapter" />
      <adapter controlType="System.Web.UI.WebControls.ImageButton" adapterType="ButtonAdapter" />
    </controlAdapters>
  </browser>
</browsers>

這裡我定義了 3 個不同的按鈕控制項配置器(Control Adapter),並且都指定到 ButtonAdapter 類別。

然後再到 App_Code 目錄下新增一個  ButtonAdapter.cs 類別檔,程式也很短,如下:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class ButtonAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter {
    protected override void OnPreRender(EventArgs e)
{ IButtonControl btn = Control as IButtonControl; // mDelete 是我自訂的 CommandName 名稱,你也可以改成你自己的名稱 if (btn.CommandName == "Delete" || btn.CommandName == "mDelete") { Control.Attributes["onclick"] = "if(!confirm('你確定要刪除嗎?')) return false;"; } base.OnPreRender(e); } }

這樣就做完了!

整個網站完全不需要再特別定義 OnClientClick="if(!confirm('你確定要刪除嗎?')) return false;" 指令,只要你的 CommandName 設定成 Delete 或 mDelete 都會自動加上 onclick 屬性,是不是一勞永逸呢!^_^

ASP.NET 2.0 的 Control Adapter 架構是我非常喜歡的一個架構,他可以針對不同的 Browser 以及針對不同的控制項進行客製化的修正,也可以用在像我今天講的這個開發技巧上,真的可以將程式碼的量降低,也降低專案的複雜度。

如果有興趣瞭解 Control Adapter 架構的人可以下載 ASP.NET 2.0 CSS Friendly Control Adapters 1.0 範例回來好好研究一下,相信會有更多的創意出現,記得回來跟我分享喔。:-)

相關連結