導言
在前面的兩篇教程中,我們看到了如何在單一頁面中顯示主/從報表, 它使用DropDownList顯示主記錄,使用GridView或DetailsView顯示詳細資料. 另外一種常見的主/從報表模式是在一個頁面中顯示主記錄而在另一個頁面中顯示詳細資料.互連網上的論壇,如www.asp.net ,就是該模式在實際應用中非常典型例子. Asp.Net論壇由多個子論壇組成: Getting Started, Web Forms, Data Presentation Controls 等等. 每個子論壇包含多個主題, 每個主題又由多個貼子組成. 在asp.net論壇首頁上列出了這些子論壇,單擊其中一個論壇會轉到ShowForum.aspx頁面, 該頁面列出了這個子論壇所包含的主題. 同樣,單擊一個主題會轉向ShowPost.aspx, 該頁面顯示所單擊主題的貼子.
在這篇教程中,我們將通過使用GridView列出供應商來實現該模式. GridView中的每行(一行便是一個供應商)包含一個”查看產品”的連結. 該連結在單擊時會轉到另外一個頁面, 這個頁面顯示選中供應商的所有產品.
Step 1: 在Filtering檔案夾下添加 SupplierListMaster.aspx 和ProductsForSupplierDetails.aspx
在第三篇教程中定義頁面結構時我們在BasicReporting, Filtering, 和 CustomFormatting檔案夾中增加了好幾個起始頁面.我們還沒有為這篇教程中添加起始頁,在Filtering檔案夾中增加兩個頁面: SupplierListMaster.aspx 和 ProductsForSupplierDetails.aspx. SupplierListMaster.aspx將會列出主記錄(供應商) ProductsForSupplierDetails.aspx將會顯示選中供應商的產品.
在建立這兩個頁面時注意要讓它們關聯Site.master主版頁面.
圖1: 在Filtering檔案夾下添加 SupplierListMaster.aspx 和ProductsForSupplierDetails.aspx
此外, 添加了兩個檔案到該項目後, 要確保相應地更新網站地圖檔Web.sitemap. 對於該篇教程只要簡單地使用下面的XML內容做為元素的子節點
提示:使用K. Scott Allen的免費的Visual Studio Site Map Macro可以協助你在新增ASP.NET頁時自動地更新網站地圖.
Step 2: SupplierListMaster.aspx中顯示供應商列表
添加SupplierListMaster.aspx 和 ProductsForSupplierDetails.aspx後,接下來就是要在SupplierListMaster.aspx頁面上建立一個顯示供應商的GridView. 添加一個GridView到頁面上並綁定到一個新的ObjectDataSource, 這個ObjectDataSource應該使用SuppliersBLL類的GetSuppliers()方法返回所有供應商.
圖2: 選擇 SuppliersBLL 類
圖3: 配置ObjectDataSource 使用GetSuppliers() 方法
我們需要在每個GridView行中包含一個”查看產品”連結,單擊時該連結會轉到ProductsForSupplierDetails.aspx頁面, 並在查詢字串(querystring)傳遞選定行的SupplierID值.比如如果使用者單擊了供應商Tokyo Traders(SupplierID值為4)的”查看產品”連結,將會轉到ProductsForSupplierDetails.aspx?SupplierID=4.
要實現該功能, 給GridView添加一個HyperLinkField列, 它會為每個GridView行增加一個連結. 首先在GridView智能標記上單擊編輯列連結. 然後在左上方的列表中選擇HyperLinkField並單擊新增把HyperLinkField添加到GridView的欄位列表中.
圖4: 添加 HyperLinkField 到GridView
HyperLinkField可以被配置為在每一個GridView行中使用相同的文本或URL值,或是讓這些值基於綁定到特定行的資料值. 要指定一個所有行都一樣的靜態值使用HyperLinkField的Text或NavigateUrl屬性. 因為我們想讓每一行的連結文本一致,設定HyperLinkField的Text屬性為”查看產品”.
圖5: 設定HyperLinkField的Text屬性為”查看產品”
要讓text 或URL基於綁定到GridView行的底層資料, 可能通過DataTextField 或 DataNavigateUrlFields指定Text或URL要從中擷取資料的資料欄位. DataTextField只能設定為一個單一的資料欄位; DataNavigateUrlFields可以設定為一個以逗號分隔的資料欄位列表. 我們需要讓TEXT或URL基於當前行的資料欄位值和一些標記. 比如在這篇教程中,我們希望 HyperLinkField的連結URL是ProductsForSupplierDetails.aspx?SupplierID=supplierID. 其中supplierID是GridView的每個行的supplierID值. 注意我們需要靜態值和資料驅動值. ProductsForSupplierDetails.aspx?SupplierID=這部分是靜態值.而supplierID部分便是資料驅動的, 它的值是每一行的SupplierID值.
要指定靜態值和資料驅動值的混合物, 使用DataTextFormatString和DataNavigateUrlFormatString屬性. 在這些屬性中按需要輸入靜態文本,要顯示DataTextField或DataNavigateUrlFields屬性中特定的欄位時使用{0}標記. 如果DataNavigateUrlFields中有多個欄位,在需要第一個欄位時使用{0}, 第二個欄位使用{1},以此類推.
對於我們這篇教程來說, 我們需要設定DataNavigateUrlFields為SupplierID, 因為我們需要使用該資料欄位自訂每行的連結.
圖6: 配置HyperLinkField 使用合適的基於SupplierID 的連結地址.
添加了HyperLinkField後, 可以自訂及重新排列GridView的欄位. 下面是我做了修改後的標記 (markup):
在瀏覽器中訪問一下SupplierListMaster.aspx. 如圖7所示, 頁面列出了所有的供應商,每個供應商包含”查看產品”連結. 單擊”查看產品”連結會轉到ProductsForSupplierDetails.aspx, 並在查詢字串中傳遞供應商的SupplierID值.
圖 7: 每個供應商都包含”查看產品”連結.
Step 3: 在ProductsForSupplierDetails.aspx上列出供應商的產品
SupplierListMaster.aspx頁面使使用者轉到ProductsForSupplierDetails.aspx, 並在查詢字串中傳遞選擇的供應商的SupplierID值. 本篇教程的最後一步是在ProductsForSupplierDetails.aspx 頁面上的GridView中顯示產品. 要實現該功能首先添加GridView到ProductsForSupplierDetails.aspx上,並使用一個新的命名為ProductsBySupplierDataSource的ObjectDataSource控制項, 該控制項調用ProductsBLL 類的GetProductsBySupplierID(supplierID)方法.
圖8: 添加一個新的命名為 ProductsBySupplierDataSource 的ObjectDataSource
圖9: 選擇ProductsBLL 類
圖10: 讓ObjectDataSource 調用 GetProductsBySupplierID(supplierID) 方法
設定資料來源精靈的最後一步是要我們提供GetProductsBySupplierID(supplierID) 方法中 supplierID 參數的來源. 要使用查詢字串中的值. 設定參數源為QueryString 並在QueryStringField文字框中輸入查詢字串值的名稱(SupplierID).
圖11: 使用查詢字串中的SupplierID值做為supplierID 參數的值
這樣就可以了! 圖12顯示了當我們在SupplierListMaster.aspx頁面中單擊Tokyo Traders供應商的”查看產品”連結時所看到的樣子.
圖12: 顯示Tokyo Traders 供應商的產品
在ProductsForSupplierDetails.aspx中顯示供應商資訊
如圖12所示, ProductsForSupplierDetails.aspx只列出了通過在查詢字串中指定的SupplierID的供應商的產品. 然而, 有些人會直接到達該頁, 這樣他們就不清楚圖12中正中顯示Tokyo Trader的產品了. 要修正這個問題, 我們可以在頁面上顯示供應商的資訊.
在GridView上方添加一個FormView. 建立一個ObjectDataSource控制項並命名為SuppliersDataSource. 該控制項調用SuppliersBLL類的GetSupplierBySupplierID(supplierID)方法.
圖13: 選擇 SuppliersBLL 類
圖14: 讓ObjectDataSource 調用 GetSupplierBySupplierID(supplierID) 方法
使用查詢字串中SupplierID的值為ProductsBySupplierDataSource的supplierID參數賦值.
圖15: 讓supplierID 參數使用查詢字串中的SupplierID 的值
在設計檢視中綁定FormView到ObjectDataSource時, Visual Studio 將會自動的建立FormView的ItemTemplate, InsertItemTemplate 和 EditItemTemplate 三個模板, 這些模板使用Label和TextBox Web控制項來呈現從ObjectDataSource返回的資料. 因為我們只需要顯示供應商資訊, 可以移除InsertItemTemplate 和 EditItemTemplat模板. 然後,編輯ItemTemplate模板,使它在標籤中顯示供應商的公司名稱, 在公司名稱下面顯示地址,城市,國家和電話號碼. 另外你也可以手工設定 FormView的 DataSourceID和建立ItemTemplate的標記. 就像我們在後面”使用ObjectDataSource顯示資料”一篇中的所作的那樣.
修改後,Formview的標記看起來應該是這樣:
<asp:FormView ID="FormView1" runat="server" DataKeyNames="SupplierID" DataSourceID="suppliersDataSource" EnableViewState="False"><ItemTemplate><h3><%# Eval("CompanyName") %></h3><p><asp:Label ID="AddressLabel" runat="server" Text='<%# Bind("Address") %>'></asp:Label><br /><asp:Label ID="CityLabel" runat="server" Text='<%# Bind("City") %>'></asp:Label>,<asp:Label ID="CountryLabel" runat="server" Text='<%# Bind("Country") %>'></asp:Label><br />Phone:<asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>'></asp:Label></p></ItemTemplate></asp:FormView>
圖16顯示了包含了供應商資訊後的ProductsForSupplierDetails.aspx頁面截屏.
圖16: 包含供應商概括資訊的產品列表
為ProductsForSupplierDetails.aspx 使用者介面應用些小技巧.
要改善該報表的使用者體驗, 應該給ProductsForSupplierDetails.aspx頁面添加點東西. 現在使用者從ProductsForSupplierDetails.aspx回到供應商列表頁面的唯一方法是單擊瀏覽器的後退按鈕. 讓我們給ProductsForSupplierDetails.aspx增加一個HyperLink控制項, 該控制項指向SupplierListMaster.aspx, 這樣就給使用者提供了另外一個回到供應商列表的方法.
圖17: 增加一個HyperLink 控制項讓使用者可以回到SupplierListMaster.aspx
如果使用者單擊了某個供應商的”查看產品”連結,而該供應商又沒有任何產品, ProductsForSupplierDetails.aspx 上的ProductsBySupplierDataSource ObjectDataSource將不會返回任何結果. 綁定到ObjectDataSource的GridView不會呈現任何標記, 在使用者的瀏覽器中顯示為空白. 要明確的告訴使用者沒有與選定供應商關聯的產品,我們可以設定GridView的EmptyDataText屬性為當出現這種情況是我們想要顯示的訊息. 我們把它設定為:” 沒有這個供應商的產品…”;
預設情況下, Northwinds資料庫中所有的供應商提供了至少一個產品. 但是, 在本篇教程中我已經手工修改了產品表, 這樣供應商Escargots Nouveaux不再關聯任何產品. 圖18顯示了修改後的供應商Escargots Nouveaux的詳細頁面.
圖18: 提示使用者該供應商沒有提供任何產品.
總結
主/從報表可以在一個頁面上同時顯示主記錄和明細記錄,在很多的網站上, 主/從屬記錄也被分開顯示在兩個頁面上. 在這篇教程中我們看到了如何?這種報表, 該報表在首頁面上用GridView顯示供應商列表, 在明細頁顯示關聯的產品列表. 首頁面上的每個供應商都包含一個指定明細頁面的連結, 並傳遞 SupplierID值. 這樣的特定行的連結使用GridView的HyperLinkField可以很容易實現.
明細頁中擷取指定供應商的產品是通過調用ProductsBLL類的GetProductsBySupplierID(supplierID)方法實現的. supplierID參數值由查詢字串中指定. 我們同樣也看到了如何在明細頁中使用FormView顯示供應商詳細資料
下一篇教程是主/從報表的最後一部分. 我們將會看到如何在GridView中列出產品, GridView中的每行有一個選擇按鈕. 單擊選擇按鈕會在同一頁的DetailsView中顯示這個產品的詳細資料.
祝編程愉快!
作者簡介
Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用微軟Web技術。Scott是個獨立的技術諮詢顧問,培訓師,作家,最近完成了將由Sams出版社出版的新作,24小時內精通ASP.NET 2.0。他的聯絡電郵為mitchell@4guysfromrolla.com,也可以通過他的部落格http://scottonwriting.net/與他聯絡。