使用重複項控件和 DataList (VB) 跨兩個頁面的主要/詳細數據篩選
在本教學課程中,我們將探討如何跨兩個頁面分隔主要/詳細數據報表。 在 [主版] 頁面中,我們使用 Repeater 控件來轉譯類別清單,當按兩下時,會將使用者帶至 「詳細數據」頁面,其中兩欄 DataList 會顯示屬於所選類別的產品。
簡介
在 [跨兩頁篩選的主要/詳細數據篩選 ] 教學課程中,我們已使用 GridView 檢查此模式,以顯示系統中的所有供應商。 此 GridView 包含 HyperLinkField,其會轉譯為第二頁的連結,並在 SupplierID
查詢字串中傳遞 。 第二頁使用 GridView 列出所選供應商所提供的這些產品。
您也可以使用 DataList 和 Repeater 控制項來完成這類雙頁主版/詳細數據報表。 唯一的差異在於 DataList 和 Repeater 都不支援 HyperLinkField 控件。 相反地,我們必須新增 HyperLink Web 控件或錨點 HTML 元素, (<a>
控件內的 ItemTemplate
) 。 然後,您可以使用宣告式或程序設計方法來自定義 HyperLink NavigateUrl
的屬性或錨點 href
的屬性。
在本教學課程中,我們將探索使用 Repeater 控件在單一頁面上列出點符清單中的類別的範例。 每個清單專案都會包含類別的名稱和描述,而類別名稱會顯示為第二頁的連結。 按兩下此連結會讓使用者前往第二個頁面,其中 DataList 會顯示屬於所選類別的產品。
步驟 1:在點符清單中顯示類別
建立任何主要/詳細數據報表的第一個步驟是從顯示「主要」記錄開始。 因此,我們的第一個工作是在 「主版」頁面中顯示類別。 CategoryListMaster.aspx
開啟 資料夾中的頁面DataListRepeaterFiltering
,新增 Repeater 控制件,然後從智慧標記選擇新增 ObjectDataSource。 設定新的 ObjectDataSource,讓它從 CategoriesBLL
類別的 GetCategories
方法存取其數據 (請參閱圖 1) 。
圖 1:將 ObjectDataSource 設定為使用 CategoriesBLL
類別的方法 GetCategories
, (按兩下即可檢視完整大小的影像)
接下來,定義 Repeater 的範本,使其將每個類別名稱和描述顯示為點符清單中的專案。 讓我們還不擔心每個類別連結至詳細數據頁面。 以下顯示 Repeater 和 ObjectDataSource 的宣告式標記:
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource1"
EnableViewState="False">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# Eval("CategoryName") %> - <%# Eval("Description") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
完成此標記之後,請花一點時間檢視我們的進度。 如圖 2 所示,重複項會轉譯為點符清單,其中顯示每個類別的名稱和描述。
圖 2:每個類別都會顯示為點符清單專案, (按兩下即可檢視完整大小的影像)
步驟 2:將類別名稱轉換成詳細數據頁面的連結
若要允許使用者顯示指定類別的「詳細數據」信息,我們需要新增每個點符清單專案的連結,按兩下時,會將使用者移至第二頁 (ProductsForCategoryDetails.aspx
) 。 接著,第二頁會使用 DataList 顯示所選類別的產品。 為了判斷單擊連結的類別,我們必須透過一些機制將按下的 CategoryID
類別傳遞給第二頁。 將純量數據從一個頁面傳送到另一個頁面的最簡單、最簡單方式是透過 querystring,這是我們將在本教學課程中使用的選項。 特別是, ProductsForCategoryDetails.aspx
頁面會預期選取 categoryID
的值會透過名為 CategoryID
的查詢字串字段傳遞。 例如,若要檢視有 1 個 CategoryID
的 [飲料] 類別產品,使用者將會造訪 ProductsForCategoryDetails.aspx?CategoryID=1
。
若要在 Repeater 中為每個點符清單專案建立超連結,我們需要將 HyperLink Web 控件或 HTML 錨點專案新增至 ItemTemplate
(<a>
) 。 在針對每個數據列顯示超連結相同的案例中,任一種方法都已足夠。 針對重複項,我偏好使用錨點元素。 若要使用錨點元素,請將 Repeater 的 ItemTemplate 更新為:
<li>
<a href='ProductsForCategoryDetails.aspx?CategoryID=<%# Eval("CategoryID") %>'>
<%# Eval("CategoryName") %>
</a> - <%# Eval("Description") %>
</li>
請注意, CategoryID
可以直接插入錨點元素的 href
屬性中;不過,若要這麼做,請務必使用單引號 (來分隔 href
屬性值,並記下引號) ,因為 Eval
屬性內的 href
方法會以引號分隔其字串 ("CategoryID"
) 。 或者,您也可以改用 HyperLink Web 控件:
<li>
<asp:HyperLink runat="server" Text='<%# Eval("CategoryName") %>'
NavigateUrl='<%# "ProductsForCategoryDetails.aspx?CategoryID=" &
Eval("CategoryID") %>'>
</asp:HyperLink>
- <%# Eval("Description") %>
</li>
請注意 URL ProductsForCategoryDetails.aspx?CategoryID
的靜態部分 — 會使用字串串連直接附加至數據系結語法內的結果 Eval("CategoryID")
。
使用 HyperLink 控制件的其中一個優點是,如有需要,可以從 Repeater 的 ItemDataBound
事件處理程式以程式設計方式存取。 例如,您可能會想要將類別名稱顯示為文字,而不是沒有相關聯產品之類別的連結。 這類檢查可以在事件處理程式中 ItemDataBound
以程序設計方式執行;對於沒有相關聯產品的類別,HyperLink 的 NavigateUrl
屬性可以設定為空白字串,因而導致該特定類別名稱轉譯為純文本 (而非連結) 。 如需根據事件處理程式以程式設計邏輯ItemDataBound
格式化 DataList 和 Repeater 內容的詳細資訊,請參閱根據 DataList 和 Repeater 的數據設定格式化教學課程。
如果您跟著做,請隨意在頁面中使用錨點元素或 HyperLink 控件方法。 不論方法為何,透過瀏覽器檢視頁面時,每個類別名稱都應該轉譯為的連結 ProductsForCategoryDetails.aspx
,並傳入適用的 CategoryID
值 (請參閱圖 3) 。
圖 3:類別名稱現在連結至 ProductsForCategoryDetails.aspx
(按下即可檢視完整大小的影像)
步驟 3:列出屬於所選類別的產品
完成 CategoryListMaster.aspx
頁面之後,我們就可以開始注意實作「詳細數據」頁面 ProductsForCategoryDetails.aspx
。 開啟此頁面,將 DataList 從 [工具箱] 拖曳至 Designer,並將其 屬性設定ID
為 ProductsInCategory
。 接下來,從 DataList 的智慧標記選擇將新的 ObjectDataSource 新增至頁面,並將其命名為 ProductsInCategoryDataSource
。 設定它,使其呼叫 ProductsBLL
類別的 GetProductsByCategoryID(categoryID)
方法;將 INSERT、UPDATE 和 DELETE 索引標籤中的下拉式清單設定為 [無]) (。
圖 4:將 ObjectDataSource 設定為使用 ProductsBLL
類別的方法 GetProductsByCategoryID(categoryID)
, (按兩下即可檢視完整大小的影像)
GetProductsByCategoryID(categoryID)
由於 方法接受輸入參數 (categoryID
) ,因此[選擇數據源精靈] 提供我們指定參數來源的機會。 使用 QueryStringField CategoryID
將參數來源設定為 QueryString。
圖 5:使用 Querystring 欄位 CategoryID
作為參數的來源 (按兩下即可檢視完整大小的影像)
如先前教學課程中所見,完成 [選擇數據源精靈] 之後,Visual Studio 會自動為列出每個數據功能變數名稱和值的 DataList 建立 ItemTemplate
。 將此範本取代為只列出產品名稱、供應商和價格的範本。 此外,將 DataList 的 RepeatColumns
屬性設定為 2。 這些變更之後,DataList 和 ObjectDataSource 的宣告式標記看起來應該如下所示:
<asp:DataList ID="ProductsInCategory" DataKeyField="ProductID" RepeatColumns="2"
DataSourceID="ProductsInCategoryDataSource" EnableViewState="False"
runat="server">
<ItemTemplate>
<h5><%# Eval("ProductName") %></h5>
<p>
Supplied by <%# Eval("SupplierName") %><br />
<%# Eval("UnitPrice", "{0:C}") %>
</p>
</ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ProductsInCategoryDataSource"
OldValuesParameterFormatString="original_{0}" runat="server"
SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID" QueryStringField="CategoryID"
Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
若要以動作檢視此頁面,請從 CategoryListMaster.aspx
頁面開始;接下來,按兩下類別項目符號清單中的連結。 這麼做會帶您前往 ProductsForCategoryDetails.aspx
,並 CategoryID
透過querystring 傳遞 。 中的 ProductsInCategoryDataSource
ProductsForCategoryDetails.aspx
ObjectDataSource 接著只會取得指定類別的這些產品,並將其顯示在 DataList 中,這會針對每個數據列轉譯兩個產品。 圖 6 顯示檢視 [飲料] 時的螢幕快照 ProductsForCategoryDetails.aspx
。
圖 6:顯示影像:每列顯示兩個 (按鍵即可檢視全大小影像)
步驟 4:顯示ProductsForCategoryDetails.aspx上的類別資訊
當使用者按兩下中的 CategoryListMaster.aspx
類別時,會前往 ProductsForCategoryDetails.aspx
並顯示屬於所選類別的產品。 不過,在 中 ProductsForCategoryDetails.aspx
,沒有選取類別的視覺提示。 一位使用者,表示按兩下 [訂閱],但意外按兩下 [Condiments],在到達 ProductsForCategoryDetails.aspx
之後便無法實現其錯誤。 為了減輕這種潛在問題,我們可以在頁面頂端 ProductsForCategoryDetails.aspx
顯示所選類別的相關信息,也就是其名稱和描述。
若要達成此目的,請在 中的 ProductsForCategoryDetails.aspx
Repeater 控件上方新增 FormView。 接下來,從名為的 FormView 智慧標記 CategoryDataSource
將新的 ObjectDataSource 新增至頁面,並將其設定為使用 CategoriesBLL
類別的 GetCategoryByCategoryID(categoryID)
方法。
圖 7:透過 CategoriesBLL
類別的方法 GetCategoryByCategoryID(categoryID)
存取類別的相關信息, (按兩下即可檢視完整大小的影像)
ProductsInCategoryDataSource
如同步驟 3 中新增的 ObjectDataSource,CategoryDataSource
's Configure Data Source 精靈會提示我們輸入方法輸入參數的來源GetCategoryByCategoryID(categoryID)
。 使用與之前完全相同的設定,將參數來源設定為 QueryString,並將 QueryStringField 值 CategoryID
設定為 (請參閱圖 5) 。
完成精靈之後,Visual Studio 會自動為 FormView 建立 ItemTemplate
、 EditItemTemplate
和 InsertItemTemplate
。 因為我們提供唯讀介面,所以您可以隨意移除 EditItemTemplate
和 InsertItemTemplate
。 此外,您也可以隨意自定義 FormView 的 ItemTemplate
。 拿掉多餘的範本並自定義 ItemTemplate 之後,您的 FormView 和 ObjectDataSource 宣告式標記看起來應該如下所示:
<asp:FormView ID="FormView1" runat="server" DataKeyNames="CategoryID"
DataSourceID="CategoryDataSource" EnableViewState="False" Width="100%">
<ItemTemplate>
<h3>
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Bind("CategoryName") %>' />
</h3>
<p>
<asp:Label ID="DescriptionLabel" runat="server"
Text='<%# Bind("Description") %>' />
</p>
</ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="CategoryDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategoryByCategoryID" TypeName="CategoriesBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID" Type="Int32"
QueryStringField="CategoryID" />
</SelectParameters>
</asp:ObjectDataSource>
圖 8 顯示透過瀏覽器檢視此頁面時的螢幕快照。
注意
除了 FormView 之外,我也會在 FormView 上方新增 HyperLink 控件,讓使用者回到 (CategoryListMaster.aspx
) 類別清單。 請隨意將此連結放在其他地方或完全省略。
圖 8:類別資訊現在會顯示在頁面頂端, (按兩下即可檢視完整大小的影像)
步驟 5:如果沒有任何產品屬於選取的類別,則顯示訊息
不論是否有任何相關聯的產品,頁面 CategoryListMaster.aspx
都會列出系統中的所有類別。 如果使用者按兩下沒有相關聯產品的類別,將不會轉譯 中的 ProductsForCategoryDetails.aspx
DataList,因為其數據源不會有任何專案。 如過去教學課程中所見,GridView 會提供 EmptyDataText
屬性,可用來指定在數據源中沒有記錄時顯示的文字訊息。 可惜的是,DataList 和 Repeater 都沒有這類屬性。
為了顯示訊息,通知用戶選取的類別沒有相符的產品,我們需要將標籤件新增至頁面,其 Text
屬性會指派給訊息,以便在沒有相符產品的情況下顯示。 然後,我們需要根據 DataList 是否包含任何專案,以程式設計方式設定其 Visible
屬性。
若要達成此目的,請從在 DataList 下方新增標籤開始。 將屬性 ID
設定為 NoProductsMessage
,並將其 Text
屬性設定為 [沒有所選類別的產品...]接下來,我們需要根據是否系結任何數據系結至 ProductsInCategory
DataList,以程式設計方式設定此標籤Visible
的屬性。 在數據系結至 DataList 之後,必須進行此指派。 針對 GridView、DetailsView 和 FormView,我們可以為控件的事件 DataBound
建立事件處理程式,該事件處理程式會在數據系結完成之後引發。 不過,DataList 和 Repeater DataBound
都沒有可用的事件。
在此特定範例中,我們可以在事件處理程式中Page_Load
指派 Label 的 Visible
屬性,因為數據會在頁面Load
的事件之前指派給 DataList。 不過,此方法在一般情況下無法運作,因為 ObjectDataSource 中的數據可能會在頁面生命週期稍後系結至 DataList。 例如,如果顯示的數據是以另一個控件中的值為基礎,例如使用DropDownList來顯示主要/詳細數據報表來保存「主要」記錄時,數據可能不會重新系結至數據 Web 控件,直到 PreRender
頁面生命週期中的階段為止。
一個適用於所有案例的解決方案,就是在系結 或的項目類型Item
時,將 屬性指派Visible
給 False
DataList 的 ItemDataBound
(或 ItemCreated
) 事件處理程式。AlternatingItem
在這種情況下,我們知道數據源中至少有一個數據項,因此可以隱藏 NoProductsMessage
標籤。 除了這個事件處理程式之外,我們也需要 DataList DataBinding
事件的事件處理程式,我們將 Label 的 Visible
屬性初始化為 True
。 由於事件 DataBinding
會在事件之前 ItemDataBound
引發,因此 Label 的 Visible
屬性一開始會設定為 True
;不過,如果有任何數據項,則會將其設定為 False
。 下列程式代碼會實作此邏輯:
Protected Sub ProductsInCategory_DataBinding(sender As Object, e As EventArgs) _
Handles ProductsInCategory.DataBinding
'Show the Label
NoProductsMessage.Visible = True
End Sub
Protected Sub ProductsInCategory_ItemDataBound(s As Object, e As DataListItemEventArgs) _
Handles ProductsInCategory.ItemDataBound
'If we have a data item, hide the Label
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = _
ListItemType.AlternatingItem Then
NoProductsMessage.Visible = False
End If
End Sub
Northwind 資料庫中的所有類別都與一或多個產品相關聯。 若要測試這項功能,我已手動調整本教學課程的 Northwind 資料庫,並將與 [產生] 類別相關聯的所有產品重新指派為 [ CategoryID
(CategoryID
= 7) ], (= 8) 。 透過選擇 [新增查詢] 並使用下列 UPDATE
語句,即可從 [伺服器總管] 完成此作業:
UPDATE Products SET
CategoryID = 8
WHERE CategoryID = 7
據以更新資料庫之後,返回 CategoryListMaster.aspx
頁面並按兩下 [產生] 連結。 由於不再有任何屬於 [產生] 類別的產品,您應該會看到「選取的類別沒有產品...」訊息,如圖 9 所示。
圖 9:如果沒有屬於選取類別的產品, (按兩下即可檢視完整大小的影像)
摘要
雖然主要/詳細數據報表可以在單一頁面上同時顯示主要和詳細數據記錄,但在許多網站中,它們會跨兩個網頁分開。 在本教學課程中,我們探討如何使用 「master」 網頁中的重複項,以及 [詳細數據] 頁面中所列的相關聯產品,在點符清單中列出類別,以實作這類主要/詳細數據報表。 主版網頁中的每個清單專案都包含沿著數據列 CategoryID
值傳遞之詳細數據頁面的連結。
在擷取指定供應商這些產品的詳細數據頁面中,是透過 ProductsBLL
類別的 GetProductsByCategoryID(categoryID)
方法來完成。 參數 categoryID
值是以宣告方式使用 CategoryID
querystring 值做為參數來源來指定。 我們也探討如何使用 FormView 在詳細數據頁面中顯示類別詳細數據,以及如果沒有屬於所選類別的產品,如何顯示訊息。
快樂的程序設計!
關於作者
Scott Mitchell 是 1998 年以來,1998 年與 Microsoft Web 技術合作的 七篇 ASP/ASP.NET 書籍和 4GuysFromRolla.com 作者。 Scott 是獨立的顧問、訓練者和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格連到,也可以透過其部落格來存取,網址為 http://ScottOnWriting.NET。
特別感謝...
本教學課程系列是由許多實用的檢閱者所檢閱。 本教學課程的首席檢閱者是 Zack Jones 和 Liz Shulok。 想要檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應