2012年6月30日 星期六

利用GridView、DetailView製作Master-Details 主表明細

Master-Details (主表明細、主細表) 是每個系統(購物系統、新聞系統、進銷存系統…)都會用到的功能,這篇文章主要是說明利用Visual Studio 2010 現有的控制項來完成簡易的主細表。

範例如下:Master主表用來顯示標題title,按下該欄位最右方的select選取按鈕,就可以看見該篇文章的詳細內容。

◎以上程式範例AspNet38_1.aspx,如在頁框下不能操作,請開新視窗操作
◎如果有問題歡迎您提出,dnowba很需要有人和我一起討論

1、設計資料表:這個部分就省略了,Master-Details 主細表的設計配合資料表,資料表是關聯式的,也就是二個資料表彼此之間有pk值互相關聯。這篇文章的重點不是在這裡,所以省略。

2、網頁的佈置:因為Master-Details 是很常使用到的功能,所以在Visual Studio也有對應的控制項,一般來說Master主表用GridView控制項、Details明細表用DetailsView控制項。在頁面上就先拉出這二個資料表。
image

3、Master主表的資料繫結:如下圖,用很簡單的select陳述式從資料庫撈出資料;另外在GridView上啟用「選取」按鈕image

4、Details明細表的資料繫結,因為明細表是依照GridView上選擇了哪個欄位來呈現的,所以設定上要使用where子句,詳細的設定如下:

image

image

image

關於where子句中的來源設定,還有很多,比方說
Control:控制項,在頁面上有的控制項系統都會偵測並放進下拉選單讓你挑選
Cookie/Session:狀態管理,是所有網頁的標準(php、jsp…等都可以通用的標準),用來暫時存放一些資料,使用的範疇不大一樣。
QueryString:不同的網頁用來接收/傳遞值的一種變數

image

image

image

上頭的步驟設定完了以後,基本的樣子就有了,因為DetailsView是在GridView選取後才會呈現明細資料的,所以「第一次進入網頁」時DetailsView是絕對沒有資料顯示的,我們可以依照邏輯設計一下畫面,在DetailsView上選擇「編輯樣板」
image

跳出樣板模式後,選擇EmtyDataTemplate,這個datarow用途是「當沒有資料時,顯示的樣板」,我們直接在樣板編輯處加入「尚未選取任何資料」
image

這樣子的話,當您「第一次進入網頁(就是還沒有選GridView裡的任何一列時」,因為DetailsView 的where子句並沒有繫結到任何資料,所以DetailsView 是沒有資料的,這個時候就會呼叫出EmtyDataTemplate上的東西。

上面的樣板可以設計成圖片樣式更美觀,但重點是邏輯上要處理好,EmtyDataTemplate是當找不到資料表上的相關紀錄時才會跑出來的row,所以文字敘述上若是用「抱歉,找不到資料」的話,對客戶端使用時就會有怪怪的感覺,畢竟使用者又還沒開始找,系統就先說了找不到。

為了符合邏輯,也許可以偷吃步,把EmtyDataTemplate的文字敘述部分改成
:請「選取」Master主表上的文章,可以進一步觀看文章明細,如下圖,這樣子的話邏輯是比較正常(但比較違反EmtyDataTemplate的原意),又可以兼任畫面的操作提示文字的工作。image

像上面這樣的方法是比較「混水摸魚」的方式,而且雖然一時之間好像邏輯正確,但是你很難保證你的操作邏輯和使用者是一樣的,搞不好他的操作順序一樣你不一樣,就看出破綻了。如果時間、功力足夠的話,再專業一點的寫法還是有的


範例的修正

反正第一次進入時,DetailsView一定是不會有資料的,所以我們乾脆就等「當GridView」有某列被選取時,再觸發DetailsView的資料繫結。
所以在頁面設計上,我們還是和前面一樣,不用改動什麼,只是一開始我們先把DetailsView和SqlDataSource2 (請看頁面佈置那張圖) 之間的連結先斷掉。
斷掉的方式很簡單,只要在DetailsView的屬性設定上,把DataSourceID=”SqlDataSource2” 先拿掉就好了(下圖反白處)。
image

ADO.NET就是一種將「資料」(如sql資料庫裡的資料表) 倒入「容器」(如.net的控制項) 的方法,這個方法就是databinding(資料繫結、資料綁定),也可以說databinding是二者之間溝通的橋樑。至於什麼時候才把這個橋搭起來呢?當然是「當GridView有一最被選擇的時候」,所以我們要在GridView的事件裡重新databind一次,這就要寫後置程式碼了:

    Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles GridView1.SelectedIndexChanged
        Me.DetailsView1.DataSourceID = Me.SqlDataSource2.ID
    End Sub

程式碼自已寫的只有一行,要注意的是寫在什麼「事件」上,下面為範例網頁,這樣設計的話,除了邏輯近乎完美,也另外有個好處,就是節省了資源,畢竟第一次進入網頁,如果detialview明明找不到關聯資料,還是要和資料庫的server連一次線,進去依where子句找一遍資料…這些都會耗費server端的資源,能省則省啦。

◎以上程式範例AspNet38.aspx,如在頁框下不能操作,請開新視窗操作
◎如果有問題歡迎您提出,dnowba很需要有人和我一起討論

4 則留言:

  1. 您好,
    我想請問一下
    如果是在GridView的title欄位,放入HyperLinkField,想讓他連結到另一個網頁去查看新聞內容,應該要怎麼設定另一的網頁中的DetailView?

    回覆刪除
    回覆
    1. 把title的label改成HyperLink控制項,再用資料繫結+傳統HTML傳遞變數的方式(Request.QueryString)來做。

      如果你還不大了解的話,可以參考我的這篇文章「用ListView做一個搜尋引擎webform」裡頭有提到

      刪除
    2. 不客氣,有問題歡迎多多發問,有不對的地方也請指教

      刪除

Related Posts Plugin for WordPress, Blogger...
// Dnow Function