緣起:
3/26 那時不少的時間在弄文章標題說的事情,雖然在功能做到 70%
時才發現不需要這樣搞 (花了 7 小時),但是這個過程讓我又對 GridView
有更多的了解,所以覺得很有必要寫下來。
話說,公司那時在做稽查,我負責的專案有被抽查,還好都沒事,聽說如果被記警告的話,那些獎金好像都會沒了。
RowDataBound:
先講這個事件,之前我的這篇文章有談到,那時候的資料來源是 DataTable,然後在 RowDataBound 裡用
e.Row.Cells[index].Text 來拿值。我這次是要用 List<自訂Class>
來當資料來源,然後將資料綁到對應的控制項。
前台程式
GridView 有三個 Column,第一個跟第三個是
TextBox,第二個是一個 DropDownList,性別的選項,有男跟女。
再來是後台的程式
30~51行 : 我們的資料
Class。
53~57行 :
為下拉選單設計的 Enum。
14~24行 :
模擬從資料庫撈出資料,用我們自己寫的 MyData 的 Constructor
來建立每個資料,並將它放進 List 中,最後指定 myGridView 的 DataSource,再
DataBind。
30~32行 : 在 RowDataBind
事件裡,從 .e.Row 裡用 FindControl 找出每個控制項。
34~36行 : 用 DataBinder.Eval 來取得資料,第一個傳入的項目是
e.Row.DataItem,第二個是 MyData Class
的欄位名稱,要注意資料型態的轉換。
最後呈現的結果會是這樣
加入新一列:
我在前台加入一個按鈕,使用者點擊後,GridView
會在最下方加入新的一列。為了在 PostBack 後還保留每列的使用者輸入,所以需要把
GridView 每個 Row 的控制項的值給抓出來
前台
13行 : 加入一個 Button
再來是後台程式碼
47~66行 : 將 myGridView
的每列控制項所存的值取出,存回 MyData class,最後回傳
List<MyData>。
50行 : myGridView.Rows
取得所有的 Row,用 GridViewRow 來遊歷每一列。
52~54行 : 呼叫 GridViewRow 的
findControl 來找到每個控制項。
56~60行 :
將每個控制項的值取出,存到變數中。Enum 可以用 Enum.TryParse 來解析 String。
62、65行 : 用記錄的變數來 new
一個 MyData,存到 List 中,最後回傳 List。
39~45行 : 新增列按鈕的 click
事件。
41行 : 用我們寫的 _RetrieveData
先把 myGridView 的資料取出。
42行 : 在 List
最後面加入一個 MyData
43、44行 : 重新指定
myGridView 的 DataSource
完成後,開啟我們的網頁,點擊按鈕後,它會新增一列出來
刪除指定列:
現在,我要在 myGridView 加入一個新的 column,裡面放的是一個
"刪除"
的按鈕。在實做刪除資料前,我要先能夠得知是哪一列的刪除按鈕被點擊,所以開始寫測試的程式碼
前台程式碼
15行 : 加入 "litTest" 的
Literal,用來顯示是哪一列的刪除鈕被點擊。
17行 : GridView 加入
OnRowCommand 事件。
37~41行 : 放刪除按鈕的
Column。我注意到,如果 CommandName 叫 "delete" 的話,ASP 會直接幫我們觸發
Delete 的事件,所以我這邊才叫它 "deleteRow"。
後台程式碼,由於只比上次多了 myGridView_RowCommand
這個方法,所以就單獨截它出來講
3行 : RowCommand
傳進來的是 GridViewCommandEventArgs 型態的參數,比對 CommandName
來選擇要執行的動作。
5行 : 可以用 CommandSource
來取得事件的觸發者,這裡是 Button。
6行 : 從這裡學到的,可以用 NamingContainer 來取得它所屬的 GridViewRow。
8行 : 從 GridViewRow 的
RowIndex 可以得知它是第幾列 (從0開始算)。
執行程式,點擊第一列的刪除按鈕,可以看到 Literal 顯示
0
既然能成功取得要刪除的列的 index,那刪除也就簡單了,修改我們的 myGridView_RowCommand 事件,呼叫 myGridView 的 DeleteRow,傳入 gridViewRow.Index
但是呢,事情好像沒有我們想像的簡單,在我們開啟網頁,點擊按鈕後,它跳出錯誤。
17行 : myGridView 加入
OnRowDeleting 事件。跟前次的主要差別是多了 myGridView_RowDeleting 事件
後台的完整程式碼會是這樣
78~84行 : myGridView_RowDeleting 事件。
80行 : 把 myGridView 現存的資料取出。
81行 : RowDeleting 會傳入 GridViewDeleteEventArgs 參數,可以從 RowIndex 得知是哪列被刪,搭配 List 的 RemoveAt 方法來移除資料。
82、83行 : 重新指定 DataSource 並 Bind。
這樣,之後不管是在新增或刪除列,其它列的資料就不會因為 PostBack 而消失不見。
沒有留言:
張貼留言