搜尋此網誌

2022年11月1日 星期二

ASP 的 CustomControl 搭配 GridView

緣起:


    這個問題是我上禮拜碰到的,只不過那時沒時間把它給記下來,假日的時候又在混。今天回到租屋處後覺得閒閒的,原本想好好玩個魔物放鬆,打個 30 分鐘後,手把沒電,哭啊,雖然也可以邊充邊玩啦,但我想讓它靜靜的充飽電,所以就。

    話說,今天萬聖節,我做了一個以前都沒做過的事,那就是在特殊節日送禮物給朋友,我用 LINE 禮物買,超方便的,有信用卡真的很方便,但也瞬間噴了我 1900 多,我送太多人了,總共有 10 個。

    回想起以前國小還國中時,我都很期待這個節日,我大姐會去金玉堂買很多零食,印象最深的就是方型巧克力跟裡面有果醬的棉花糖,不過她買那些最主要不是要給我們吃的,而是要送給她的好朋友,而且還包裝得很講究,用各種色彩繽紛的小袋子跟緞帶裝飾,她很喜歡做這些手工類的事。我跟我二姐就只能分到剩下的糖果,雖然沒有一大堆糖果可以狂吃是很可惜,但還是會覺得很開心。

    講太多跟這篇無關的東西了,開始進入正題。


Custom Control:


    ASP 把網頁上的各種元件都看成是一個 Control,那些常見的 Button、Literal 都是繼承自 WebControl,公司的專案中也有不少的自制 Control,最常見的就一個選擇時間日期的選擇器。

    可以先在專案下建一個專門放 Custom Control 的資料夾,然後對那個資料夾點右鍵 -> 加入 -> 新增項目,跳出視窗後,選擇 WebForms 使用者控制項


    我這邊把它叫 "TestControl",完成後,會出現 TestControl.ascx 那些檔案,它也是一樣有分前端跟後端,點進 ascx,給它加兩個 button 跟一個 label


    button 的 click 事件很簡單,就只是改變那個 label 的文字


    要在某個頁面使用的話,就在頁面的 aspx 檔上面加入

<%@ Register Src="~/Common/TestControl.ascx" TagPrefix="uc1" TagName="TestControl"%>


    這樣就能註冊自訂的控制項,Src 是檔案置,TagPrefix 跟 TagName 設定控制項的名稱。完成後就可以在 form 裡面加入自己的控制項,那個元件的標籤就是我們先前設定的 TagPrefix 跟 TagName


    執行程式,一切正常,按鈕也都有反應



搭配 GridView 生成多個 Control:


    在 index.aspx 裡弄個 GridView


    TestControl 要放在 ItemTemplate 裡,再來是程式的部份,跟上篇教的做法差不多

在 Page_Load 時載入資料

生成 DataTable 的 method


生成的 table

    看起來是沒問題,可以當我點擊上面的 button 時,它會跑出錯誤


    這問題搞我搞很久,在網上到處查關鍵字,試了許多方法都沒用,最後發現... 原來是在 Page_Load 那邊,我需要先辨識觸發事件時,是不是 PostBack,因為我那個 TestControl 的 button 都有 runat="server",所以點選它們時都會做出 PostBack 的動作,導致 GridView 重新載入資料,原本的控制項就不見了,所以在 Page_Load 裡要寫這樣


    之後再點那些按鈕就正常了



對動態產生的控制項做操作:


    雖然我們有給那個在 GridView 裡的 TestControl ID,但我們在程式中輸入它的 ID 時,編輯器會跟我們說找不到。如果要透過 ID 存取的話,要在 DataBound 時,從 Row 裡用 findControl 把它給抓出。

    我們先給 TestControl 加一個 public 的方法,傳值設定 label 的文字


    回到 index.aspx,設定 GridView 的 OnRowDataBound 事件


    然後是那個 gridView_RowDataBound 方法


    它會傳一個 GridViewRowEventArgs,它有一個 Row 欄位,可以從它得到被綁定的那一列,要確定 RowType 是 DataRow 才能繼續,因為會觸發這事件的還有 header 跟 footer 那些列。再來呼叫 Row 的 FindControl,裡面傳我們 TestControl 的 ID,它會回傳 Control 類別,要把它轉成 TestControl 類別,最後呼叫我們先前新增的方法,把它設成列裡面 id 欄的值,可以透過 Cells[index] 來取得特定欄位

    最後是結果



沒有留言:

張貼留言