共用方式為


在 DataList 和 Repeater 中的自訂按鈕 (C#)

斯科特·米切爾

下載 PDF

在本教學課程中,我們將建置一個使用重複器列出系統中類別的使用者介面,每個類別都會提供按鈕,以使用 BulletedList 控制項顯示其相關聯的產品。

簡介

在過去的十七個 DataList 和 Repeater 教學課程中,我們製作了唯讀範例,以及可進行編輯和刪除操作的範例。 為了在 DataList 中增強編輯和刪除功能,我們在 DataList 的 ItemTemplate 中新增了一些按鈕,這些按鈕在被點擊時會造成回傳,並引發與按鈕的 CommandName 屬性對應的 DataList 事件。 例如,將按鈕新增到 ItemTemplate,其 CommandName 屬性值為 「Edit」 時,會導致在回傳時 DataList 的 EditCommand 引發;而 CommandName 屬性值為 「Delete」 的會引發 DeleteCommand

除了 [編輯和刪除] 按鈕之外,DataList 和 Repeater 控件也可以包含 Button、LinkButton 或 ImageButton,按一下時會執行一些自定義的伺服器端邏輯。 在這次教學中,我們將建置使用重覆器來列出系統分類的介面。 針對每個類別,重複程式會包含按鈕,以使用 BulletedList 控件來顯示類別的相關聯產品(請參閱圖 1)。

按兩下 [顯示產品連結] 在項目符號清單中顯示類別目錄的產品

圖 1:點擊 [顯示產品連結] 將類別的產品顯示為項目符號清單(點擊以查看完整大小的影像

步驟 1:新增自定義按鈕教學網頁

在瞭解如何新增自定義按鈕之前,讓我們先花點時間在網站專案中建立我們在本教學課程所需的 ASP.NET 頁面。 首先,新增名為 CustomButtonsDataListRepeater的新資料夾。 接下來,將下列兩個 ASP.NET 頁面新增至該資料夾,請務必讓每個頁面與 Site.master 主版頁面產生關聯:

  • Default.aspx
  • CustomButtons.aspx

新增自定義 Buttons-Related 教學課程的 ASP.NET 頁面

圖 2:新增自訂 Buttons-Related 教學課程的 ASP.NET 頁面

就像在其他資料夾中一樣, Default.aspx 資料夾中 CustomButtonsDataListRepeater 會列出其區段中的教學課程。 回想一下, SectionLevelTutorialListing.ascx 使用者控件會提供這項功能。 將此使用者控制項從 [方案總管] 拖曳至頁面的設計檢視以新增至 Default.aspx

將 SectionLevelTutorialListing.ascx 使用者控件新增至 Default.aspx

圖 3:將使用者控制項新增 SectionLevelTutorialListing.ascxDefault.aspx按兩下以檢視完整大小的影像

最後,將頁面新增到檔案 Web.sitemap 中。 具體來說,使用 DataList 和 Repeater <siteMapNode>在分頁和排序之後新增下列標記:

<siteMapNode
    url="~/CustomButtonsDataListRepeater/Default.aspx"
    title="Adding Custom Buttons to the DataList and Repeater"
    description="Samples of DataList and Repeater Reports that Include
                  Buttons for Performing Server-Side Actions">
    <siteMapNode
        url="~/CustomButtonsDataListRepeater/CustomButtons.aspx"
        title="Using Custom Buttons in the DataList and Repeater's Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons within templates." />
</siteMapNode>

更新 Web.sitemap之後,請花點時間透過瀏覽器檢視教學課程網站。 左側功能表現在包含編輯、插入和刪除教學的項目。

網站地圖現在包含自定義按鈕教學的條目

圖 4:網站地圖現已包含自訂按鈕教學的項目列表

步驟 2:新增類別清單

在本教學課程中,我們需要建立一個重複控制項,其中列出所有類別,並包含一個顯示產品連結按鈕,當點擊時,會在項目符號列表中顯示相關聯的類別產品。 讓我們先建立一個簡單的重複器,用來列出系統中的類別。 首先打開 AdvancedDAL 資料夾中的 EncryptingConfigSections.aspx 頁面。 將 Repeater 從 [工具箱] 拖曳至設計工具,並將其 屬性設定 IDCategories。 接下來,從 Repeater 的智慧標記建立新的數據源控件。 具體而言,請建立名為 CategoriesDataSource 的新 ObjectDataSource 控件,以從 CategoriesBLL 類別 s GetCategories() 方法選取其數據。

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

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

不同於 DataList 控件,Visual Studio 會根據數據源建立預設值 ItemTemplate ,必須手動定義 Repeater 的範本。 此外,Repeater 的範本必須以宣告方式建立和編輯,也就是說,重複器的智慧標記中並沒有「編輯範本」選項。

點選左下角的 [來源] 索引標籤,新增 ItemTemplate,在 <h3> 元素中顯示類別名稱,並在段落標籤中顯示其描述;包括一個 SeparatorTemplate,在每個類別之間顯示水平線 (<hr />)。 同時新增LinkButton,其 Text 屬性設定為 [顯示產品]。 完成這些步驟之後,您的頁面宣告式標記看起來應該如下所示:

<asp:Repeater ID="Categories" DataSourceID="CategoriesDataSource"
    runat="server">
    <ItemTemplate>
        <h3><%# Eval("CategoryName") %></h3>
        <p>
            <%# Eval("Description") %>
            [<asp:LinkButton runat="server" ID="ShowProducts">
                Show Products</asp:LinkButton>]
        </p>
    </ItemTemplate>
    <SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

圖 6 顯示透過瀏覽器檢視的頁面。 會列出每個類別名稱和描述。 按兩下 [顯示產品] 按鈕會導致回傳,但尚未執行任何動作。

每個類別的名稱和描述都會顯示,並配有一個「顯示產品」的連結按鈕

圖 6:顯示每個類別的名稱和描述,以及連結按鈕顯示產品(點擊以查看完整大小的影像

步驟 3:點擊顯示產品連結按鈕時執行 Server-Side 運算

每當按下 DataList 或 Repeater 範本內的 Button、LinkButton 或 ImageButton 時,就會發生回傳,且 DataList 或 Repeater 的ItemCommand事件被引發。 除了 ItemCommand 事件以外,若按鈕的 CommandName 屬性被設成保留字串(Delete、Edit、Cancel、Update 或 Select)之一,DataList 控件可能會觸發另一個更具體的事件,然而,ItemCommand 事件始終會被觸發。

在 DataList 或 Repeater 控件中點擊按鈕時,我們通常需要傳遞是哪個按鈕被按下(因為控件內可能有多個按鈕,例如 [編輯] 及 [刪除] 按鈕),還可能需要傳遞一些額外資訊(例如按鈕所屬項目的主鍵值)。 Button、LinkButton 和 ImageButton 提供兩個屬性,其值會傳遞至 ItemCommand 事件處理程式:

  • CommandName 字串通常用來識別範本中的每個按鈕
  • CommandArgument 通常用來保存某些數據欄位的值,例如主鍵值

在此範例中,使用數據系結語法CommandName,將LinkButton s CategoryID 屬性設定為 ShowProducts,並將當前記錄的主鍵值CommandArgument系結至 CategoryArgument='<%# Eval("CategoryID") %>' 屬性。 指定這兩個屬性之後,LinkButton 的宣告式語法看起來應該如下所示:

<asp:LinkButton runat="server" CommandName="ShowProducts"
    CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">
    Show Products</asp:LinkButton>

按鈕被點擊時,就會發生回傳,並引發 DataList 或 Repeater 的 ItemCommand 事件。 事件處理程式會傳遞按鈕 s CommandNameCommandArgument 值。

建立 Repeater s ItemCommand 事件的事件處理程式,並記下傳遞至事件處理程式的第二個參數(名為 e)。 第二個參數的類型 RepeaterCommandEventArgs 如下,具有下列四個屬性:

  • CommandArgument 已點選按鈕的屬性值 CommandArgument
  • CommandName 按鈕 s CommandName 屬性的值
  • CommandSource 指向已點擊的按鈕控制項的參考
  • Item 指向 RepeaterItem 的參考,其中包含所按按鈕;每個綁定到重複器的記錄都呈現為 RepeaterItem

由於選取的類別 s CategoryID 是透過 CommandArgument 屬性傳入,因此我們可以取得與事件處理程式中 ItemCommand 所選類別相關聯的產品集合。 然後,這些產品可以系結至尚未新增的 ItemTemplate BulletedList 控件。 接著,剩下的就是新增 BulletedList、在事件處理程式中 ItemCommand 參考它,並將它系結至所選類別的產品集,我們將在步驟 4 中加以處理。

備註

DataList 的 ItemCommand 事件處理程式會接收到一個 DataListCommandEventArgs 類型的物件,該物件提供與 RepeaterCommandEventArgs 類別相同的四個屬性。

步驟 4:在點符清單中顯示選取類別的產品

選取的類別 s 產品可以使用任意數目的控制件顯示在 Repeater s ItemTemplate 內。 我們可以新增另一個巢狀 Repeater、DataList、DropDownList、GridView 等等。 不過,由於我們想要將產品顯示為點符清單,因此我們將使用 BulletedList 控件。 返回 CustomButtons.aspx 頁面的宣告式標記後,在 Show Products LinkButton 的後面新增一個 BulletedList 控制項。 將 BulletedLists 設定 IDProductsInCategory。 BulletedList 會顯示透過 DataTextField 屬性指定的數據欄位值;由於此控制項將有系結至該欄位的產品資訊,請將 屬性設定 DataTextFieldProductName

<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"
    runat="server"></asp:BulletedList>

在事件處理程式中 ItemCommand ,使用 e.Item.FindControl("ProductsInCategory") 參考此控件,並將它系結至與所選類別相關聯的產品集合。

protected void Categories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    if (e.CommandName == "ShowProducts")
    {
        // Determine the CategoryID
        int categoryID = Convert.ToInt32(e.CommandArgument);
        // Get the associated products from the ProudctsBLL and bind
        // them to the BulletedList
        BulletedList products =
            (BulletedList)e.Item.FindControl("ProductsInCategory");
        ProductsBLL productsAPI = new ProductsBLL();
        products.DataSource =
            productsAPI.GetProductsByCategoryID(categoryID);
        products.DataBind());
    }
}

在事件處理程式中 ItemCommand 執行任何動作之前,請務必先檢查傳入 CommandName的值。 由於ItemCommand事件處理程式會在按一下任何按鈕時引發,因此如果範本中有多個按鈕,請使用CommandName值來辨識要採取的動作。 檢查CommandName 在這裡是多餘的,因為我們只有一個按鈕,但養成這種習慣是個好主意。 接下來,從選取類別的 CategoryID 屬性擷取 CommandArgument 。 然後會參照範本中的 BulletedList 控件,並系結至 ProductsBLL 類別的 GetProductsByCategoryID(categoryID) 方法結果。

在先前使用 DataList 內按鈕的教學課程中,例如 DataList 中編輯和刪除資料的概觀,我們透過 DataKeys 集合判斷指定專案的主鍵值。 雖然此方法適用於 DataList,但 Repeater 沒有 DataKeys 屬性。 相反地,我們必須使用替代方法來提供主鍵值,例如透過按鈕 s CommandArgument 屬性,或將主鍵值指派給範本內的隱藏標籤 Web 控件,並使用 將值讀回 ItemCommand 事件處理程式 e.Item.FindControl("LabelID")

完成 ItemCommand 事件處理程序之後,請花點時間在瀏覽器中測試此頁面。 如圖 7 所示,點選 [顯示產品] 連結會造成回傳,並在 BulletedList 中顯示所選類別的產品。 此外,請注意,即使按兩下其他類別顯示產品連結,此產品資訊仍會維持不變。

備註

如果您要修改此報表的行為,因此一次只列出一個類別的產品,只要將 BulletedList 控制件的 EnableViewState 屬性設定為 False

BulletedList 可用來顯示所選類別的產品

圖 7:項目符號清單用來顯示所選類別的產品(按兩下即可檢視完整大小的影像

總結

DataList 和 Repeater 控制項可以在其範本中包含任意數目的 Button、LinkButtons 或 ImageButton。 按一下這些按鈕時,會導致回傳並引發 ItemCommand 事件。 若要將自定義伺服器端動作與按下的按鈕產生關聯,請建立 ItemCommand 事件的事件處理程式。 在此事件處理程式中,請先檢查傳入 CommandName 值,以判斷已按下哪個按鈕。 您可以選擇性地透過按鈕 s CommandArgument 屬性提供其他資訊。

快樂的程序設計!

關於作者

斯科特·米切爾,七本 ASP/ASP.NET 書籍和 4GuysFromRolla.com 創始人的作者,自1998年以來一直與Microsoft Web 技術合作。 斯科特擔任獨立顧問、教練和作家。 他的最新書是《Sams 24小時自學ASP.NET 2.0》。 可以聯絡他 mitchell@4GuysFromRolla.com。

特別感謝

本教學系列已由許多熱心的評論者審閱。 本教學課程的主要檢閱者是 Dennis Patterson。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果是,請在 mitchell@4GuysFromRolla.com給我留言。