共用方式為


使用具有詳細資料 DataList 的主要記錄項目符號清單的主要/詳細 (VB)

由斯科特· 米切爾

下載 PDF

在本教學課程中,我們將將上一個教學課程的雙頁主版/詳細數據報表壓縮成單一頁面,其中顯示畫面左側的類別名稱點符清單,以及畫面右側選取的類別產品。

簡介

在上一個教學課程中,我們探討如何跨兩個頁面分隔主要/詳細數據報表。 在主版頁面中,我們使用重複項控件來轉譯類別的項目符號清單。 每個類別名稱都是一個超連結,當單擊時,會將使用者帶到詳細數據頁面,其中兩欄 DataList 會顯示屬於所選類別的產品。

在本教學課程中,我們會將雙頁教學課程壓縮成單一頁面,並在畫面左側顯示類別名稱點符清單,其中每個類別名稱都會轉譯為LinkButton。 按兩下其中一個類別名稱LinkButtons會引發回傳,並將選取的類別產品系結至畫面右側的兩欄 DataList。 除了顯示每個類別的名稱之外,左側的 Repeater 也會顯示指定類別的總產品數目(請參閱圖 1)。

類別的名稱和產品總數會顯示在左側

圖 1:類別的名稱和產品總數會顯示在左側 (按兩下以檢視完整大小的影像

步驟 1:在畫面左部分顯示重複項

在本教學課程中,我們需要將類別專案符號清單顯示在所選類別產品左側。 網頁內的內容可以使用標準 HTML 元素段落標記、非中斷空格、 <table> s 等等,或透過級聯樣式表單 (CSS) 技術來定位。 到目前為止,我們所有的教學課程都使用 CSS 技術進行定位。 當我們在主版頁面和網站導覽教學課程的主版頁面中建置瀏覽使用者介面時,我們使用絕對定位,指出瀏覽清單和主要內容的精確圖元位移。 或者,CSS 可用來透過 浮動將某個元素放在另一個專案的右邊或左邊。 我們可以將重複項移至 DataList 左邊的重複項,讓類別清單出現在所選類別產品左邊

CategoriesAndProducts.aspx從資料夾開啟頁面,DataListRepeaterFiltering並將 新增至頁面重複程式和 DataList。 將 Repeater s ID 設定為 Categories ,並將 DataList s 設定為 CategoryProducts。 移至 [來源] 檢視,並將 Repeater 和 DataList 控件放在自己的 <div> 元素內。 也就是說,先將 Repeater 括在元素內 <div> ,然後緊接在 Repeater 之後的 <div> DataList 中。 此時的標記看起來應該如下所示:

<div>
    <asp:Repeater ID="Categories" runat="server">
    </asp:Repeater>
</div>
<div>
    <asp:DataList ID="CategoryProducts" runat="server">
    </asp:DataList>
</div>

若要將 Repeater 浮動至 DataList 左邊,我們需要使用 float CSS 樣式屬性,如下所示:

<div>
    Repeater
</div>
<div>
    DataList
</div>

float: left; 浮出第二 <div> 個元素左邊的第一個專案。 widthpadding-right 設定會指出第一<div>個 swidth,以及元素內容與其右邊界之間<div>新增多少填補。 如需 CSS 中浮動專案的詳細資訊,請參閱 Floatutorial

讓我們改為在名為 FloatLeftStyles.css建立新的 CSS 類別,而不是直接透過第一個<p>元素 的 style 屬性指定樣式設定:

.FloatLeft
{
    float: left;
    width: 33%;
    padding-right: 10px;
}

然後,我們可以將 取代 <div><div class="FloatLeft">

新增 CSS 類別並在頁面中設定標記 CategoriesAndProducts.aspx 之後,請移至設計工具。 您應該會看到重複項浮動到 DataList 左邊(雖然現在兩者都只是顯示為灰色方塊,因為我們尚未設定其數據源或範本)。

重複程式會浮動至 DataList 的左邊

圖 2:重複項會浮動至 DataList 的左邊(按兩下即可檢視完整大小的影像

步驟 2:判斷每個類別的產品數目

使用 Repeater 和 DataList 周圍標記完成之後,我們即可將類別數據系結至 Repeater 控制件。 不過,如圖 1 所示的類別項目符號清單,除了每個類別的名稱之外,我們也必須顯示與類別相關聯的產品數目。 若要存取這項資訊,我們可以:

  • 從 ASP.NET 頁面的程式代碼後置類別判斷這項資訊。 鑒於特定 categoryID ,我們可以藉由呼叫 ProductsBLL 類別 s GetProductsByCategoryID(categoryID) 方法來判斷相關聯的產品數目。 這個方法會傳 ProductsDataTable 回 物件,其 Count 屬性會指出存在多少 ProductsRow 個 ,這是指定 categoryID之產品的數目。 我們可以為 Repeater 建立 ItemDataBound 事件處理程式,針對系結至 Repeater 的每個類別,呼叫 ProductsBLL 類別 s GetProductsByCategoryID(categoryID) 方法,並在輸出中包含其計數。
  • CategoriesDataTable更新具類型的 DataSet 中的 ,以包含數據行NumberOfProducts 然後我們可以更新 GetCategories() 中的 CategoriesDataTable 方法,以包含這項資訊,或者,依目前方式保留 GetCategories() ,並建立名為 GetCategoriesAndNumberOfProducts()的新CategoriesDataTable方法。

讓我們來探索這兩種技術。 第一種方法較容易實作,因為我們不需要更新數據存取層;不過,它需要與資料庫進行更多的通訊。 事件處理程式中類別 s GetProductsByCategoryID(categoryID) 方法的ItemDataBound呼叫ProductsBLL會針對 Repeater 中顯示的每個類別新增額外的資料庫呼叫。 這項技術有 N + 1 個資料庫呼叫,其中 N 是重複項中顯示的類別數目。 使用第二種方法時,會傳回產品計數,其中包含類別 s GetCategories() (或GetCategoriesAndNumberOfProducts()) 方法中每個類別CategoriesBLL的相關信息,因此只會對資料庫進行一次訪問。

判斷 ItemDataBound 事件處理程式中的產品數目

判斷 Repeater ItemDataBound 事件處理程式中每個類別的產品數目,不需要對現有的數據存取層進行任何修改。 所有修改都可以直接在 CategoriesAndProducts.aspx 頁面中進行。 首先,透過 Repeater 的智慧標記新增名為 CategoriesDataSource 的 ObjectDataSource。 接下來,設定 CategoriesDataSource ObjectDataSource,使其從 CategoriesBLL 類別 s GetCategories() 方法擷取其數據。

將 ObjectDataSource 設定為使用 CategoriesBLL 類別 s GetCategories() 方法

圖 3:將 ObjectDataSource 設定為使用 CategoriesBLL 類別 s GetCategories() 方法(按兩下以檢視完整大小的影像

重複程式中的每個 Categories 項目都必須可點選,而且按兩下時,DataList 會針對 CategoryProducts 選取的類別顯示這些產品。 這可以藉由讓每個類別成為超連結,連結回這個相同頁面 (CategoriesAndProducts.aspx),但透過查詢字串傳遞 CategoryID ,就像我們在上一個教學課程中看到的一樣。 這種方法的優點是,顯示特定類別產品的頁面可由搜尋引擎加入書籤並編製索引。

或者,我們可以將每個類別設為LinkButton,這是我們將在本教學課程中使用的方法。 LinkButton 會在使用者的瀏覽器中轉譯為超連結,但按兩下時會引發回傳;在回傳時,必須重新整理 DataList s ObjectDataSource,才能顯示屬於所選類別的產品。 在本教學課程中,使用超連結比使用LinkButton更有意義;不過,可能有其他使用 LinkButton 比較有利的情況。 雖然超連結方法很適合此範例,但讓我們改用LinkButton來探索。 如我們所見,使用LinkButton會帶來一些不會與超連結一起出現的挑戰。 因此,在本教學課程中使用 LinkButton 將會反白顯示這些挑戰,並協助針對我們可能想要使用 LinkButton 而不是超連結的案例提供解決方案。

注意

建議您使用 HyperLink 控制件或 <a> 元素取代 LinkButton 來重複本教學課程。

下列標記顯示 Repeater 和 ObjectDataSource 的宣告式語法。 請注意,Repeater 的範本會將每個項目的項目符號清單轉譯為 LinkButton:

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory"></asp:LinkButton></li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

注意

在本教學課程中,Repeater 必須啟用其檢視狀態(請注意 Repeater 宣告式語法中省略 EnableViewState="False" 的 。 在步驟 3 中,我們將為 Repeater 事件 ItemCommand 建立事件處理程式,在此事件中,我們將更新 DataList s ObjectDataSource 集合 SelectParameters 。 不過,如果停用檢視狀態,則重複程式 ItemCommand不會引發。

屬性值ViewCategory為的 ID LinkButton沒有其Text屬性集。 如果我們剛想要顯示類別名稱,我們會透過數據系結語法以宣告方式設定 Text 屬性,如下所示:

<asp:LinkButton runat="server" ID="ViewCategory"
    Text='<%# Eval("CategoryName") %>' />

不過,我們想要同時顯示類別的名稱 屬於該類別的產品數目。 您可以從 Repeater 事件處理程式 ItemDataBound 擷取這項資訊,方法是呼叫 ProductBLL 類別 s GetCategoriesByProductID(categoryID) 方法,並判斷產生的 ProductsDataTable記錄傳回數目,如下列程式代碼所示:

Protected Sub Categories_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
    ' Make sure we're working with a data item...
    If e.Item.ItemType = ListItemType.Item OrElse _
        e.Item.ItemType = ListItemType.AlternatingItem Then
        ' Reference the CategoriesRow instance bound to this RepeaterItem
        Dim category As Northwind.CategoriesRow = _
            CType(CType(e.Item.DataItem, System.Data.DataRowView).Row, _
                Northwind.CategoriesRow)
        ' Determine how many products are in this category
        Dim productsAPI As New NorthwindTableAdapters.ProductsTableAdapter
        Dim productCount As Integer = _
            productsAPI.GetProductsByCategoryID(category.CategoryID).Count
        ' Reference the ViewCategory LinkButton and set its Text property
        Dim ViewCategory As LinkButton = _
            CType(e.Item.FindControl("ViewCategory"), LinkButton)
        ViewCategory.Text = _
            String.Format("{0} ({1:N0})", category.CategoryName, productCount)
    End If
End Sub

首先,我們會確保使用數據項 (其中 ItemType 一個 是 ItemAlternatingItem),然後參考 CategoriesRow 剛剛系結至目前 RepeaterItem的實例。 接下來,我們會藉由建立 類別的 ProductsBLL 實例、呼叫其 GetCategoriesByProductID(categoryID) 方法,以及判斷使用 Count 屬性傳回的記錄數目,來判斷此類別的產品數目。 最後, ViewCategory ItemTemplate 中的 LinkButton 是參考,其 Text 屬性會設定為 CategoryNameNumberOfProductsInCategory),其中 NumberOfProductsInCategory 會格式化為具有零小數位數的數位。

注意

或者,我們可以將格式化函式新增至 ASP.NET 頁程式代碼後置類別,以接受類別和CategoryNameCategoryID值,並傳回CategoryName與類別中產品數目串連的 (呼叫 方法所GetCategoriesByProductID(categoryID)決定)。 這類格式化函式的結果可以宣告方式指派給LinkButton s Text 屬性,以取代事件處理程式的需求 ItemDataBound 。 如需 使用格式化函式的詳細資訊,請參閱 GridView 控件 中的 Using TemplateFields 或 格式化 DataList 和 Repeater Based Data 教學課程。

新增此事件處理程序之後,請花點時間透過瀏覽器測試頁面。 請注意,每個類別如何列在點符清單中,顯示類別的名稱和與類別相關聯的產品數目(請參閱圖 4)。

每個類別的名稱和產品數目都會顯示

圖 4:顯示每個類別的名稱和產品數目(按兩下以檢視完整大小的影像

更新CategoriesDataTableCategoriesTableAdapter以包含每個類別的產品數目

我們不會在系結至重複程式時判斷每個類別的產品數目,而是藉由調整 CategoriesDataTable 數據存取層 中的和 CategoriesTableAdapter 以原生方式包含此資訊,來簡化此程式。 若要達成此目的,我們必須加入新的數據行, CategoriesDataTable 以保存相關聯的產品數目。 若要將新數據行加入 DataTable,請開啟 [具類型的數據集] (App_Code\DAL\Northwind.xsd),以滑鼠右鍵按兩下 DataTable 以修改,然後選擇 [新增/ 資料行]。 將新數據行新增至 CategoriesDataTable (請參閱圖 5)。

將新數據行新增至 CategoriesDataSource

圖 5:將 [新增數據行] 新增至 CategoriesDataSource按兩下以檢視完整大小的影像

這會新增名為 Column1的新數據行,您可以直接輸入不同的名稱來變更。 將此新資料列重新命名為 NumberOfProducts。 接下來,我們需要設定此數據行的屬性。 按兩下新的資料行,然後移至 屬性視窗。 將數據行的 DataType 屬性從 System.String 變更為 System.Int32 ,並將 屬性設定 ReadOnlyTrue,如圖 6 所示。

設定新數據行的 DataType 和 ReadOnly 屬性

圖 6:設定 DataType 新資料行的 和 ReadOnly 屬性

CategoriesDataTable雖然 現在有數據行NumberOfProducts,但其值不是由任何對應的 TableAdapter 查詢所設定。 如果我們想要每次擷取類別資訊時傳回這類資訊,我們可以更新 GetCategories() 方法以傳回此資訊。 不過,如果我們只需要擷取罕見實例中類別的相關聯產品數目(例如只針對本教學課程),我們可以依原樣離開 GetCategories() ,並建立傳回這項資訊的新方法。 讓我們使用這個后一種方法,建立名為 GetCategoriesAndNumberOfProducts()的新方法。

若要新增這個新 GetCategoriesAndNumberOfProducts() 方法,請以滑鼠右鍵按兩下 CategoriesTableAdapter ,然後選擇 [新增查詢]。 這會顯示 TableAdapter 查詢設定精靈,我們在先前的教學課程中多次使用過此精靈。 針對這個方法,藉由指示查詢使用傳回數據列的臨機操作 SQL 語句,以啟動精靈。

使用臨機操作 SQL 語句建立方法

圖 7:使用臨機操作 SQL 語句建立方法 (按兩下以檢視完整大小的影像

SQL 語句會傳回數據列

圖 8:SQL 語句傳回資料列(按兩下以檢視完整大小的影像

下一個精靈畫面會提示我們查詢使用。 若要傳回每個類別、CategoryIDCategoryName、 和 Description 字段,以及與類別相關聯的產品數目,請使用下列SELECT語句:

SELECT CategoryID, CategoryName, Description,
       (SELECT COUNT(*) FROM Products p WHERE p.CategoryID = c.CategoryID)
            as NumberOfProducts
FROM Categories c

指定要使用的查詢

圖 9:指定要使用的查詢(按下即可檢視完整大小的影像

請注意,計算與類別相關聯的產品數目的子查詢會別名為 NumberOfProducts。 此命名比對會導致這個子查詢傳回的值與 CategoriesDataTable s NumberOfProducts 數據行相關聯。

輸入此查詢之後,最後一個步驟是選擇新方法的名稱。 分別使用 FillWithNumberOfProductsGetCategoriesAndNumberOfProducts 來填滿 DataTable 並傳回 DataTable 模式。

將 New TableAdapter s 方法命名為 FillWithNumberOfProducts 和 GetCategoriesAndNumberOfProducts

圖 10:將新的 TableAdapter 命名為 方法FillWithNumberOfProducts,然後按兩下GetCategoriesAndNumberOfProducts以檢視完整大小的影像

此時,數據存取層已擴充,以包含每個類別的產品數目。 由於我們所有的表示層都會透過個別的商業規則層路由傳送至 DAL 的所有呼叫,因此我們需要將對應的 GetCategoriesAndNumberOfProducts 方法新增至 CategoriesBLL 類別:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetCategoriesAndNumberOfProducts() As Northwind.CategoriesDataTable
    Return Adapter.GetCategoriesAndNumberOfProducts()
End Function

隨著 DAL 和 BLL 完成,我們準備將此數據系結至 Categories 中的 CategoriesAndProducts.aspx重複程式! 如果您已經從 [判斷事件處理程式中的產品數目] 區段中,為 Repeater 建立 ObjectDataSource,請刪除此 ObjectDataSource 並移除 Repeater s 屬性設定;同時移除 ASP.NET 程式代碼後置類別中的 ItemDataBound 語法,將 Repeater s DataSourceID ItemDataBound 事件與事件處理程式 Handles Categories.OnItemDataBound 取消連接。

使用 Repeater 回到其原始狀態時,請透過 Repeater 的智慧標記新增名為 CategoriesDataSource 的 ObjectDataSource。 將 ObjectDataSource 設定為使用 CategoriesBLL 類別,但不要使用 方法,而是改用GetCategories()GetCategoriesAndNumberOfProducts()物件DataSource(請參閱圖 11)。

將 ObjectDataSource 設定為使用 GetCategoriesAndNumberOfProducts 方法

圖 11:將 ObjectDataSource 設定為使用 GetCategoriesAndNumberOfProducts 方法 (按兩下以檢視完整大小的影像

接下來,更新 ItemTemplate ,以便使用數據系結語法以宣告方式指派LinkButton s Text 屬性,並同時包含 CategoryNameNumberOfProducts 數據欄位。 Repeater 和 CategoriesDataSource ObjectDataSource 的完整宣告式標記如下:

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory"
                Text='<%# String.Format("{0} ({1:N0})", _
                    Eval("CategoryName"), Eval("NumberOfProducts")) %>' />
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategoriesAndNumberOfProducts" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

更新 DAL 以包含 NumberOfProducts 資料行所轉譯的輸出與使用 ItemDataBound 事件處理程式方法相同(請參閱圖 4,以查看顯示類別名稱和產品數目的重複程式螢幕快照)。

步驟 3:顯示選取類別的產品

此時,我們有 Categories 重複項顯示類別清單,以及每個類別中的產品數目。 Repeater 會針對按兩下時導致回傳的每個類別使用LinkButton,此時我們需要在DataList中 CategoryProducts 顯示所選類別的產品。

我們面臨的一個挑戰是如何讓 DataList 只顯示所選類別的這些產品。 在主 圖形/詳細數據使用可選取的主方格檢視與詳細數據檢視 教學課程中,我們已瞭解如何建置可選取數據列的 GridView,其中選取的數據列詳細數據會顯示在相同頁面上的 DetailsView 中。 GridView s ObjectDataSource 會使用 ProductsBLL s GetProducts() 方法傳回所有產品的相關信息,而 DetailsView s ObjectDataSource 則使用 GetProductsByProductID(productID) 方法擷取所選產品的相關信息。 參數 productID 值是以宣告方式提供,方法是將它與 GridView s SelectedValue 屬性的值產生關聯。 不幸的是,Repeater 沒有 SelectedValue 屬性,而且無法做為參數來源。

注意

這是在重複程式中使用LinkButton時出現的其中一項挑戰。 如果我們改用超連結透過querystring傳入 CategoryID ,我們就可以使用該QueryString字段做為參數值的來源。

不過,在我們擔心 Repeater 缺少 SelectedValue 屬性之前,讓我們先將 DataList 系結至 ObjectDataSource 並指定其 ItemTemplate

從 DataList 的智慧標記中,選擇新增名為 CategoryProductsDataSource 的新 ObjectDataSource,並將其設定為使用 ProductsBLL 類別 s GetProductsByCategoryID(categoryID) 方法。 由於本教學課程中的 DataList 提供唯讀介面,因此可以隨意將 INSERT、UPDATE 和 DELETE 索引卷標的下拉式清單設定為 [無]。

將 ObjectDataSource 設定為使用 ProductsBLL 類別 s GetProductsByCategoryID(categoryID) 方法

圖 12:將 ObjectDataSource 設定為使用 ProductsBLL 類別 s GetProductsByCategoryID(categoryID) 方法(按兩下以檢視完整大小的影像

GetProductsByCategoryID(categoryID)由於 方法需要輸入參數 (categoryID),[設定數據源精靈] 可讓我們指定參數的來源。 在 GridView 或 DataList 中列出類別之後,我們會將 [參數來源] 下拉式清單設定為 [控件],並將 ControlID 設定為 ID 數據 Web 控件的 。 不過,由於 Repeater 缺少 SelectedValue 屬性,因此無法當做參數來源使用。 如果您檢查,您會發現 ControlID 下拉式清單只包含一個控件 ID``CategoryProductsID 也就是 DataList 的 。

目前,將 [參數來源] 下拉式清單設定為 [無]。 當 Repeater 中按兩下類別 LinkButton 時,我們最終會以程式設計方式指派此參數值。

請勿指定 categoryID 參數的參數來源

圖 13:請勿指定 categoryID 參數的參數來源(按兩下以檢視完整大小的影像

完成 [設定數據源精靈] 之後,Visual Studio 會自動產生 DataList s ItemTemplate。 將此預設值 ItemTemplate 取代為我們在上一個教學課程中使用的範本;此外,請將 DataList s RepeatColumns 屬性設定為 2。 進行這些變更之後,DataList 及其相關聯的 ObjectDataSource 宣告式標記看起來應該如下所示:

<asp:DataList ID="CategoryProducts" runat="server" DataKeyField="ProductID"
    DataSourceID="CategoryProductsDataSource" RepeatColumns="2"
    EnableViewState="False">
    <ItemTemplate>
        <h5><%# Eval("ProductName") %></h5>
        <p>
            Supplied by <%# Eval("SupplierName") %><br />
            <%# Eval("UnitPrice", "{0:C}") %>
        </p>
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="CategoryProductsDataSource"
    OldValuesParameterFormatString="original_{0}"  runat="server"
    SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:Parameter Name="categoryID" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

目前, CategoryProductsDataSource 永遠不會設定 ObjectDataSource s categoryID 參數,因此檢視頁面時不會顯示任何產品。 我們需要做的是, CategoryID 根據 Repeater 中按兩下的類別設定此參數值。 這引進了兩個挑戰:第一,我們如何判斷在重複項中 ItemTemplate 按兩下LinkButton的時機;第二,我們如何判斷 CategoryID 按兩下LinkButton的對應類別的 ?

Button 和 ImageButton 控制件之類的 LinkButton 具有 Click 事件和 Command 事件。 此 Click 事件的設計目的是要只注意已按兩下LinkButton。 不過,除了注意到已按兩下LinkButton之外,我們還需要將一些額外的信息傳遞給事件處理程式。 如果是這種情況,則可以將LinkButton和 CommandName CommandArgument 屬性指派給這個額外資訊。 然後,按兩下LinkButton時,其Command事件會引發 (而不是其 Click 事件),而事件處理程式會傳遞 和 CommandArgument 屬性的值CommandName

Command當事件從 Repeater 的範本內引發時,Repeater 的 ItemCommand 事件就會引發,並傳遞CommandName按兩下的 LinkButton (或 Button 或 ImageButton) 的和 CommandArgument 值。 因此,若要判斷已按兩下 Repeater 中的 LinkButton 類別,我們需要執行下列動作:

  1. CommandName Repeater s ItemTemplate 中 LinkButton 的 屬性設定為一些值(我已使用 ListProducts )。 藉由設定此值 CommandName ,LinkButton 事件 Command 會在按兩下LinkButton時引發。
  2. 將 LinkButton s CommandArgument 屬性設定為目前專案 的值 CategoryID
  3. 建立 Repeater s ItemCommand 事件的事件處理程式。 在事件處理程式中,將 CategoryProductsDataSource ObjectDataSource s CategoryID 參數設定為傳入 CommandArgument的值。

類別重複項的下列 ItemTemplate 標記會實作步驟 1 和 2。 請注意值 CommandArgument 如何使用資料系結語法來指派數據項 CategoryID

<ItemTemplate>
    <li>
        <asp:LinkButton CommandName="ListProducts"  runat="server"
            CommandArgument='<%# Eval("CategoryID") %>' ID="ViewCategory"
            Text='<%# string.Format("{0} ({1:N0})", _
                Eval("CategoryName"), Eval("NumberOfProducts")) %>'>
        </asp:LinkButton>
    </li>
</ItemTemplate>

每當建立ItemCommand事件處理程式時,請務必先檢查傳入CommandName值,因為重複程式內的任何 Button、LinkButton 或 ImageButton 引發的任何Command事件都會引發ItemCommand事件。 雖然我們目前只有一個這樣的 LinkButton,但未來我們(或小組上的另一位開發人員)可能會將其他按鈕 Web 控件新增至重複程式,當單擊時,會引發相同的 ItemCommand 事件處理程式。 因此,最好一律確定您檢查 屬性, CommandName 而且只有在符合預期的值時,才繼續進行程式設計邏輯。

確保傳入CommandName的值等於 ListProducts 之後,事件處理程式接著會將 ObjectDataSource s CategoryID 參數指派CategoryProductsDataSource給傳入CommandArgument的值。 對 ObjectDataSource 的 SelectParameters 這項修改會自動使 DataList 重新繫結至數據源,顯示新選取類別的產品。

Protected Sub Categories_ItemCommand(source As Object, e As RepeaterCommandEventArgs) _
    Handles Categories.ItemCommand
    ' If it's the "ListProducts" command that has been issued...
    If String.Compare(e.CommandName, "ListProducts", True) = 0 Then
        ' Set the CategoryProductsDataSource ObjectDataSource's CategoryID parameter
        ' to the CategoryID of the category that was just clicked (e.CommandArgument)...
        CategoryProductsDataSource.SelectParameters("CategoryID").DefaultValue = _
            e.CommandArgument.ToString()
    End If
End Sub

透過這些新增功能,我們的教學課程已完成! 花點時間在瀏覽器中進行測試。 圖 14 顯示第一次瀏覽頁面時的畫面。 由於尚未選取類別,因此不會顯示任何產品。 按兩下類別,例如 [產生],會在兩欄檢視的 [產品] 類別中顯示這些產品(請參閱圖 15)。

第一次瀏覽頁面時不會顯示任何產品

圖 14:第一次瀏覽頁面時不會顯示任何產品(按兩下以檢視完整大小的影像

按兩下 [產生類別] 列出右邊的相符產品

圖 15:按兩下 [產生類別] 以滑鼠右鍵按兩下 [符合的產品] (按兩下以檢視完整大小的影像

摘要

如我們在本教學課程和先前的教學課程中所見,主要/詳細數據報表可以分散到兩個頁面,或合併在一個頁面。 不過,在單一頁面上顯示主要/詳細數據報表,對如何配置頁面上的主圖形和詳細數據記錄提出了一些挑戰。 在主 圖形/詳細數據使用可選取的主方格檢視與詳細數據檢視 教學課程中,我們有詳細數據記錄出現在主要記錄上方;在本教學課程中,我們使用 CSS 技術讓主要記錄浮動到詳細數據左邊。

除了顯示主要/詳細數據報表之外,我們也有機會探索如何擷取與每個類別相關聯的產品數目,以及如何在重複程式內單擊LinkButton (或Button或ImageButton) 時執行伺服器端邏輯。

本教學課程會使用 DataList 和 Repeater 完成主要/詳細數據報告的檢查。 下一組教學課程將說明如何將編輯和刪除功能新增至 DataList 控件。

快樂的程序設計!

深入閱讀

如需本教學課程中所討論主題的詳細資訊,請參閱下列資源:

關於作者

斯科特·米切爾,七本 ASP/ASP.NET 書籍和 4GuysFromRolla.com 創始人的作者,自1998年以來一直與Microsoft Web 技術合作。 斯科特擔任獨立顧問、教練和作家。 他的最新書是 山姆斯在24小時內 ASP.NET 2.0。 他可以到達 mitchell@4GuysFromRolla.com, 或通過他的博客,可以在 找到 http://ScottOnWriting.NET

特別感謝

本教學課程系列已由許多實用的檢閱者檢閱。 本教學課程的主要檢閱者是 Zack Jones。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果是,請將一行 mitchell@4GuysFromRolla.com放在 。