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

作者:Scott Mitchell

下載 PDF

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

簡介

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

在本教學課程中,我們會將兩頁教學課程壓縮成單一頁面,其中顯示畫面左側的類別名稱點符號清單,每個類別名稱都會轉譯為LinkButton。 按兩下其中一個類別名稱LinkButtons會引發回傳,並將選取的類別產品系結至畫面右側的兩欄 DataList。 除了顯示每個類別的名稱之外,左側的 [重複程式] 還會顯示指定類別的總產品數 (請參閱圖 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> ,然後在重複項後面直接將 DataList 放在它自己的 <div> 元素中。 此時您的標記看起來應該類似下列內容:

<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

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

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

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

新增 CSS 類別並在頁面中設定標記CategoriesAndProducts.aspx之後,請移至 Designer。 您應該會看到 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更新具型別數據集中的 ,以包含數據NumberOfProducts行。 然後,我們可以更新 GetCategories() 中的 CategoriesDataTable 方法以包含這項資訊,或者保留GetCategories()原樣,並建立稱為 GetCategoriesAndNumberOfProducts()的新CategoriesDataTable方法。

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

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

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

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

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

重複項中的每個 Categories 項目都必須可點選,按兩下時,會導致 CategoryProducts DataList 顯示所選類別的這些產品。 這可以透過讓每個類別成為超連結來完成,連結回這個相同頁面 (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>

注意

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

具有屬性值的 IDViewCategory 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

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

注意

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

新增此事件處理程序之後,請花點時間透過瀏覽器測試頁面。 請注意每個類別列在點符清單中的方式,顯示類別的名稱和與類別相關聯的產品數目, (請參閱圖 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 ,並將 ReadOnly 屬性設定為 True,如圖 6 所示。

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

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

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

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

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

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

SQL 語句會傳回數據列

圖 8:SQL 語句會傳回數據列, (按兩下即可檢視完整大小的影像)

下一個精靈畫面會提示我們查詢使用。 若要傳回每個類別的 CategoryIDCategoryNameDescription 字段,以及與類別相關聯的產品數目,請使用下列 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.aspxRepeater! 如果您已經從 [判斷事件處理程式中的 ItemDataBound 產品數目] 區段中建立 Repeater 的 ObjectDataSource,請刪除此 ObjectDataSource 並移除 Repeater 的 DataSourceID 屬性設定;同時移除 repeater 事件 ItemDataBound 與事件處理程式的連線,方法是移除 Handles Categories.OnItemDataBound ASP.NET 程式代碼後置類別中的語法。

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

將 ObjectDataSource 設定為使用 GetCategoriesAndNumberOfProducts 方法

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

接下來,更新 ItemTemplate ,以便使用數據系結語法以宣告方式指派LinkButton屬性 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 重複項顯示類別清單,以及每個類別中的產品數目。 重複程式會針對每個類別使用 LinkButton,當按兩下時,會導致回傳,此時我們需要在 DataList 中顯示所選類別的產品 CategoryProducts

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

注意

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

不過,在擔心重複項的屬性 SelectedValue 不足之前,請先將DataList系結至 ObjectDataSource 並指定其 ItemTemplate

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

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

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

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

現在,將 [參數來源] 下拉式清單設定為 [無]。 在重複程式中按兩下類別 LinkButton 時,我們最後會以程式設計方式指派此參數值。

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

圖 13:請勿為 categoryID 參數指定參數來源 (按單擊即可檢視完整大小的影像)

完成 [設定數據源精靈] 之後,Visual Studio 會自動產生 DataList s ItemTemplate。 請將此預設值 ItemTemplate 取代為我們在上一個教學課程中使用的範本;此外,請將 DataList 的 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和 CommandNameCommandArgument 屬性指派給這個額外資訊。 然後,按兩下LinkButton時,其Command事件會引發 (而不是其Click事件) ,而且事件處理程式會傳遞和 CommandArgument 屬性的值CommandName

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

  1. CommandName Repeater s ItemTemplate 中 LinkButton 的 屬性設定為一些值, (我已使用 ListProducts ) 。 藉由設定此值 CommandName ,LinkButton 事件 Command 會在按兩下LinkButton時引發。
  2. 將 LinkButton s CommandArgument 屬性設定為目前專案的值 CategoryID
  3. 建立 Repeater 事件的 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 控件。

快樂的程序設計!

深入閱讀

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

關於作者

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。 想要檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com。