ASP.NET 密技集錦 (C#)-I 2002 年 11 月號 作者 : 許嘉仁審稿 : 許薰尹文章編號 :N021101002 Server Control 使用 Client 端 Script 難易度 : 易 相關資源與開發工具 : 1. Visual Studio.NET 2. ASP.NET 3. C#.NET 難 Server Control 的好用, 大家都很清楚了, 但是結合 Client 端 Script 在 Web 開發上又有其必要性, 在這介紹幾個好用的結合方式 要做到的功能是當使用者點選這個按鈕時, 先跳出確認的對話視窗, 如圖 1: 發行人 : 劉致宏 總 主 編 : 張智凱 編 : 許薰尹 社務顧問 : 邱世萍技術編輯 : 張書源許嘉仁編輯顧問 : 鄭淑芬胡百敬楊先民羅慧真美術設計 : 魏吉芝陳昀行銷企劃 : 曹雅瑩陳秀慧發行服務 : 謝佩珊劉清滿發行所 : 毅達行銷顧問股份有限公司客戶服務 :service@netmag.com.tw 圖 1:UseScript_1.aspx 範例 使用者如果點選 Cancel 則取消這個動作, 如果點選 OK 則在頁面印出 您按了 Button1, 如圖 2 本電子刊物之所載標誌名稱分屬各該公司所有, 非經授權請勿轉載使用, 版權所有 如經查證依法律追訴 1
圖 2:UseScript_1.aspx 範例 一般 Client 端 Script 要結合 Server Control 可以直接在 Server Control 的標籤內寫即可, 例如滑鼠移到按鈕上, 按鈕的背景顏色改變成紅色, 只要 2
直接在 Server Control 的標籤內加上事件即可, 如下 : <asp:button id="button1" Text="Button" onmouseover="this.style.backgroundcolor='red'" runat="server" /> 但是如果要做到這個範例的功能所遇到的最大問題是 OnClick 事件已經被 Server 端用掉了, 如下列語法的 OnClick 事件會去執行 Server 端的程式碼 : <asp:button id="button1" Text="Button" Onclick="Afunction" runat="server" /> 那如何加入 Client 端的 OnClick 事件呢? 最常見的做法在網站討論區已經有網友 Post 出來 首先使用 VS.NET 建立一個網頁 UseScript_1.aspx, 在頁面設計視窗拖曳一個 Button 控制項, 然後要要幫這個按鈕加上 Client 端 Script 加入以下程式: private void Page_Load(object sender, System.EventArgs e) Button1.Attributes["onclick"]="javascript:return confirm(' 你確定要按嗎?')"; private void Button1_Click(object sender, System.EventArgs e) Response.Write(" 你按了 Button1"); 也就是讓網頁載入時動態在按鈕上加入 OnClick 事件以及 Client 端 Script 如果讀者的 Client 端 Script 不是簡單的幾行程式, 也可以改成呼叫函式, 例如現在要做的功能是頁面有一個 TextBox 和一個 Button, 當使用者點選按鈕, 如果 TextBox 的值是空的就提示使用者並取消點選按鈕事件, 如圖 3: 3
圖 3:UseScript_2.aspx 範例 如果使用者有輸入值, 則在頁面中印出使用者所輸入的值, 如圖 4: 圖 4:UseScript_2.aspx 範例 UseScript_2.aspx 範例要先加入 Client 端 Script 函式, 如圖 5: 4
圖 5:UseScript_2.aspx Client 端函式 UseScript_2.aspx 範例的 Server 端程式碼如圖 6: 圖 6:UseScript_2.aspx.cs 程式碼 同樣是動態加入 OnClick 事件來完成 Client 端 Script 的工作, 不過還有第三種更好的方式, 不用寫 Server 端的程式碼, 利用下列程式碼一樣可以達 5
到同樣功能, 如圖 7: 圖 7:UseScript_3.aspx.cs 程式碼 同時修改多筆資料 一般資料的修改會以修改模式和瀏覽模式切換, 一次修改一筆以及儲存一筆, 有些人需要同時修改多筆並同時儲存多筆,ASP.NET 預設提供的控制項沒有這種功能, 但是可以模擬這種功能 首先在頁面中放入三個 Button 控制項和兩個 DataList 控制項, 將 儲存 和 取消 按鈕及第二個 DataList 控制項的 Visible 屬性設為 false, 也就是先隱藏, 如圖 8: 6
圖 8:MultiEdit_1.aspx 頁面設計 然後先取得 SQL Server 的 Pubs 資料庫的 Jobs Table 的 job_id job_desc 欄位的資料, 也就是取得 DataSet, 然後編輯兩個 DataList 控制項的 Header Template, 各放入兩個 Label 控制項, 第一個 Label 控制項的寬度設死為 100px, 這是為了美觀, 如圖 9: 圖 9:MultiEdit_1.aspx 頁面設計 設定完兩個 DataList 控制項的 DataSource 屬性以及 DataMemeber 屬性, 利用 AutoFormat 美化一下控制項 然後繼續編輯其 ItemTemplate, 第一個 DataList 控制項放入兩個 Label 控制項, 一個繫結 job_id 欄位, 一個繫結 job_desc 欄位 第二個 DataList 控制項放入一個 CheckBox 控制項 一個 Label 控制項和 7
一個 TextBox 控制項,Label 控制項繫結 job_id 欄位,TextBox 控制項繫結 job_desc 欄位 兩個 DataList 控制項的第一個 Label 控制項寬度都設為 100px, 還是為了美觀 簡單來說, 所有設定都一樣, 只有繫結的控制項不同, 如圖 10: 圖 10:MultiEdit_1.aspx 頁面設計 接下來加入下列程式碼就能展現資料 : private void Page_Load(object sender, System.EventArgs e) if (!IsPostBack) BindList1(); private void BindList1() Button1.Visible=true; Button2.Visible=false; Button3.Visible=false; DataList1.Visible=true; DataList2.Visible=false; sqldataadapter1.fill(dsjobs1); DataList1.DataBind(); 展現結果如圖 11: 8
圖 11:MultiEdit_1.aspx 當使用者點選 修改 按鈕, 每一筆資料都要展現成 TextBox, 只要將 DataList1 隱藏,DataList2 展現即可, 這就是筆者所謂的模擬, 加入以下程式碼 : private void Button1_Click(object sender, System.EventArgs e) BindList2(); private void BindList2() Button1.Visible=false; Button2.Visible=true; Button3.Visible=true; DataList1.Visible=false; DataList2.Visible=true; sqldataadapter1.fill(dsjobs1); DataList2.DataBind(); 結果如圖 12: 9
圖 12:MultiEdit_1.aspx 取消 按鈕的功能比較簡單, 加入下列程式碼即可 : private void Button3_Click(object sender, System.EventArgs e) BindList1(); 這樣就能回到瀏覽模式, 最難的部分在於判斷哪幾筆資料被修改過了, 在這邊又要利用到 Client 端 Script 的技巧, 還記得前面沒用到的 CheckBox 控制項, 這是筆者用來記錄被修改過的資料是哪幾筆用的 切換到 HTML 編輯視窗, 將 DataList2 的 TextBox 控制項加入以下語法 : <asp:textbox id=textbox1 runat="server" onchange="javascript:this.parentelement.children(0).checked= true;" Text='<%#DataBinder.Eval(Container, "DataItem.job_desc")%>' Width="300px"> </asp:textbox> 此時測試網頁, 會發現只要修改 TextBox 的值, 在 LoseFocus 的時候 CheckBox 就會自動打勾, 也就是修改過這筆資料的意思 如圖 13: 10
圖 13:MultiEdit_1.aspx 最後當然要想辦法抓出哪幾筆資料被修改過, 並批次寫回資料庫, 在 儲存 按鈕的 Click 事件加入下列程式碼 : private void Button2_Click(object sender, System.EventArgs e) sqlconnection1.open(); SqlCommand cmd=new SqlCommand("update jobs set job_d esc=@job_desc where job_id=@job_id", sqlconnection1); cmd.parameters.add(new SqlParameter("@job_id",SqlDbType. SmallInt,2)); cmd.parameters.add(new SqlParameter("@job_desc",SqlDbTyp e.varchar,50)); foreach (DataListItem item in DataList2.Items) CheckBox cb=(checkbox)item.controls[1]; if (cb.checked) Label lbl=(label)item.controls[3]; TextBox txt=(textbox)item.controls[5]; cmd.parameters["@job_id"].value=lbl.text; 11
cmd.parameters["@job_desc"].value=txt.text; cmd.executenonquery(); sqlconnection1.close(); BindList1(); 透過迴圈依序抓出 CheckBox Label 和 TextBox 控制項, 經過轉型後取出裡面的值然後判斷是否有被修改, 如果有就批次寫入資料庫, 沒有就回到 瀏覽模式了 測試結果如圖 14 15: 測試範例 圖 14:MultiEdit_1.aspx 12
圖 15:MultiEdit_1.aspx 結語 : 在這篇文章中介紹兩個應用技巧, 動作不是很困難, 亦不難懂, 會活用才是 重要 希望能為讀者帶來幫助 相信以同樣的做法, 也可以在 Repeater 和 DataGrid 控制項當中來做到同樣的功能 許嘉仁 13 現任恆逸資訊教育訓練處技術副理, 擁有 MCSD 等認證, 熟悉 Web Application 開發, DHTML,COM+ 元件設計 關聯式資料庫系統分析與設計 電子商務相關技術,XML 應用程式開發,C# 與 ASP.NET 技術開發以及.NET 相關技術研究, 並為技術書籍作者及雜誌專欄作家