在 DataList (C# ) 中編輯和刪除資料的概觀

作者:Scott Mitchell

下載 PDF

雖然 DataList 缺少內建的編輯和刪除功能,但在本教學課程中,我們將瞭解如何建立支援編輯和刪除其基礎數據的 DataList。

簡介

插入、更新和刪除數據的概 觀教學課程中,我們探討如何使用應用程式架構、ObjectDataSource 和 GridView、DetailsView 和 FormView 控件來插入、更新和刪除數據。 使用 ObjectDataSource 和這三個數據 Web 控件時,實作簡單的數據修改介面是貼齊,並只涉及從智慧標記刻度複選框。 不需要撰寫任何程序代碼。

不幸的是,DataList 缺少 GridView 控件固有的內建編輯和刪除功能。 當宣告式數據源控件和無程式代碼數據修改頁面無法使用時,此遺漏功能是因為 DataList 是舊版 ASP.NET 的複本。 雖然 ASP.NET 2.0 中的 DataList 不提供與 GridView 相同的現成數據修改功能,但我們可以使用 ASP.NET 1.x 技術來包含這類功能。 此方法需要一些程序代碼,但如本教學課程所示,DataList 有一些事件和屬性可協助此程式。

在本教學課程中,我們將瞭解如何建立支援編輯和刪除其基礎數據的 DataList。 未來的教學課程將檢查更進階的編輯和刪除案例,包括輸入字段驗證、正常處理從數據存取或商業規則層引發的例外狀況等等。

注意

如同 DataList,Repeater 控制項缺少插入、更新或刪除的現用功能。 雖然可以新增這類功能,但 DataList 包含重複程式中找不到的屬性和事件,可簡化新增這類功能。 因此,本教學課程和未來檢視編輯和刪除的教學課程將著重於 DataList。

步驟 1:建立編輯和刪除教學課程網頁

在開始探索如何從 DataList 更新和刪除數據之前,讓我們先花一點時間在網站專案中建立 ASP.NET 頁面,我們將需要本教學課程和接下來幾個頁面。 首先,新增名為 EditDeleteDataList的新資料夾。 接下來,將下列 ASP.NET 頁面新增至該資料夾,請務必將每個頁面與 Site.master 主版頁面產生關聯:

  • Default.aspx
  • Basics.aspx
  • BatchUpdate.aspx
  • ErrorHandling.aspx
  • UIValidation.aspx
  • CustomizedUI.aspx
  • OptimisticConcurrency.aspx
  • ConfirmationOnDelete.aspx
  • UserLevelAccess.aspx

新增教學課程的 ASP.NET 頁面

圖 1:新增教學課程的 ASP.NET 頁面

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

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

圖 2:將使用者控件新增 SectionLevelTutorialListing.ascxDefault.aspx (按兩下即可檢視完整大小的影像)

最後,將頁面新增為檔案的專案 Web.sitemap 。 具體而言,使用 DataList 和 Repeater <siteMapNode>在 Master/Detail Reports 後面新增下列標記:

<siteMapNode
    title="Editing and Deleting with the DataList"
    description="Samples of Reports that Provide Editing and Deleting Capabilities"
    url="~/EditDeleteDataList/Default.aspx" >
    <siteMapNode
        title="Basics"
        description="Examines the basics of editing and deleting with the
                     DataList control."
        url="~/EditDeleteDataList/Basics.aspx" />
    <siteMapNode
        title="Batch Update"
        description="Examines how to update multiple records at once in a
                     fully-editable DataList."
        url="~/EditDeleteDataList/BatchUpdate.aspx" />
    <siteMapNode
        title="Error Handling"
        description="Learn how to gracefully handle exceptions raised during the
                     data modification workflow."
        url="~/EditDeleteDataList/ErrorHandling.aspx" />
    <siteMapNode
        title="Adding Data Entry Validation"
        description="Help prevent data entry errors by providing validation."
        url="~/EditDeleteDataList/UIValidation.aspx" />
    <siteMapNode
        title="Customize the User Interface"
        description="Customize the editing user interfaces."
        url="~/EditDeleteDataList/CustomizedUI.aspx" />
    <siteMapNode
        title="Optimistic Concurrency"
        description="Learn how to help prevent simultaneous users from
                     overwritting one another s changes."
        url="~/EditDeleteDataList/OptimisticConcurrency.aspx" />
    <siteMapNode
        title="Confirm On Delete"
        description="Prompt a user for confirmation when deleting a record."
        url="~/EditDeleteDataList/ConfirmationOnDelete.aspx" />
    <siteMapNode
        title="Limit Capabilities Based on User"
        description="Learn how to limit the data modification functionality
                     based on the user s role or permissions."
        url="~/EditDeleteDataList/UserLevelAccess.aspx" />
</siteMapNode>

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

網站地圖現在包含 DataList 編輯和刪除教學課程的專案

圖 3:網站地圖現在包含 DataList 編輯和刪除教學課程的專案

步驟 2:檢查更新和刪除數據的技術

使用 GridView 編輯和刪除數據很簡單,因為 GridView 和 ObjectDataSource 在一起運作。 如同 檢查與插入、更新和刪除相關的事件 教學課程中所討論,按兩下數據列的 [更新] 按鈕時,GridView 會自動指派其字段,以雙向數據系結至 UpdateParameters 其 ObjectDataSource 的集合,然後叫用該 ObjectDataSource s Update() 方法。

不幸的是,DataList 不提供任何此內建功能。 我們有責任確保使用者的值會指派給 ObjectDataSource s 參數,並呼叫其 Update() 方法。 為了協助我們進行這項工作,DataList 提供下列屬性和事件:

  • 更新或刪除時,我們必須能夠唯一識別 DataList 中的每個專案。DataKeyField 將此屬性設定為所顯示資料的主鍵欄位。 這麼做會將每個 DataList 專案的指定DataKeyField值填入 DataList DataKeys 集合
  • 當按鈕、LinkButton 或 ImageButton CommandName 設定為 [編輯] 時,就會引發此事件。EditCommand
  • 當按下 Button、LinkButton 或 ImageButton,其CommandName屬性設為 Cancel 時,就會引發此事件。CancelCommand
  • 當按下 Button、LinkButton 或 ImageButton,且CommandName其屬性設定為 Update 時,就會引發此事件。UpdateCommand
  • 當按鈕、LinkButton 或 ImageButton CommandName 設定為 Delete 時,就會引發此事件。DeleteCommand

使用這些屬性和事件時,有四種方法可用來更新和刪除 DataList 中的數據:

  1. 使用 ASP.NET 1.x 技術 時,DataList 存在於 ASP.NET 2.0 和 ObjectDataSources 之前,而且能夠透過程序設計方式完全更新和刪除數據。 這項技術會完全捨棄 ObjectDataSource,並要求我們直接從商業規則層將數據系結至 DataList,同時擷取要顯示的數據,以及在更新或刪除記錄時。
  2. 在頁面上使用單一 ObjectDataSource 控件進行選取、更新和刪除 ,而 DataList 缺少 GridView 固有的編輯和刪除功能,我們並無理由自行新增它們。 使用此方法時,我們會使用 ObjectDataSource,就像在 GridView 範例中一樣,但必須為 DataList 事件 UpdateCommand 建立事件處理程式,其中我們設定 ObjectDataSource s 參數並呼叫其 Update() 方法。
  3. 使用 ObjectDataSource 控制項進行選取,但在使用選項 2 時直接針對 BLL 進行更新和刪除 ,我們需要在事件中 UpdateCommand 撰寫一些程式代碼、指派參數值等等。 相反地,我們可以繼續使用 ObjectDataSource 進行選取,但直接對 B (LL 進行更新和刪除呼叫,例如選項 1) 。 在意見中,直接與 BLL 互動來更新數據會導致比指派 ObjectDataSource s UpdateParameters 和呼叫其 Update() 方法更容易閱讀的程序代碼。
  4. 透過多個 ObjectDataSource 使用宣告式方法 ,前三種方法都需要一些程序代碼。 如果您想要盡可能繼續使用宣告式語法,最後一個選項是在頁面上包含多個 ObjectDataSources。 第一個 ObjectDataSource 會從 BLL 擷取數據,並將它系結至 DataList。 為了更新,會新增另一個 ObjectDataSource,但直接在 DataList s EditItemTemplate中新增 。 若要包含刪除支援,還需要另 ItemTemplate一個 ObjectDataSource。 透過這種方法,這些內嵌的 ObjectDataSource 會使用 ControlParameters 宣告方式將 ObjectDataSource 參數係結至使用者輸入控件 (,而不需要以程式設計方式在 DataList UpdateCommand 事件處理程式中指定參數) 。 這種方法仍然需要一些程式代碼,我們需要呼叫內嵌的 ObjectDataSource 或Update()Delete()命令,但需要遠小於其他三種方法。 這裡的缺點是多個 ObjectDataSources 會雜亂頁面,從整體可讀性減去。

如果強制只使用其中一種方法,我選擇選項 1,因為它提供最大的彈性,而且因為 DataList 原本是設計來容納此模式。 雖然 DataList 已擴充為使用 ASP.NET 2.0 數據源控件,但它沒有官方 ASP.NET 2.0 數據 Web 控件的所有擴充點或功能, (GridView、DetailsView 和 FormView) 。 不過,選項 2 到 4 不具價值。

這和未來的編輯和刪除教學課程將會使用 ObjectDataSource 來擷取數據,以顯示和直接呼叫 BLL 來更新和刪除數據 (選項 3) 。

步驟 3:新增 DataList 並設定其 ObjectDataSource

在本教學課程中,我們將建立列出產品資訊的 DataList,併為每個產品提供編輯名稱和價格,以及完全刪除產品的能力。 特別是,我們會擷取使用 ObjectDataSource 顯示的記錄,但直接與 BLL 互動來執行更新和刪除動作。 在擔心將編輯和刪除功能實作至 DataList 之前,讓我們先取得頁面,以在唯讀介面中顯示產品。 由於我們已在先前的教學課程中檢查這些步驟,我將會快速完成這些步驟。

從開啟 Basics.aspx 資料夾中的頁面 EditDeleteDataList 開始,然後從 [設計] 檢視將 DataList 新增至頁面。 接下來,從 DataList 的智慧標記建立新的 ObjectDataSource。 因為我們正在使用產品數據,因此請將其設定為使用 ProductsBLL 類別。 若要 擷取所有 產品,請選擇 GetProducts() SELECT索引標籤中的方法。

將 ObjectDataSource 設定為使用 ProductsBLL 類別

圖 4:將 ObjectDataSource 設定為使用 ProductsBLL 類別 (按兩下即可檢視大小完整的映射)

使用 GetProducts () 方法傳回產品資訊

圖 5:使用 GetProducts() 方法傳回產品資訊 (按兩下即可檢視大小完整的影像)

DataList 與 GridView 一樣,不是專為插入新數據而設計的;因此,從 [INSERT] 索引標籤的下拉式清單中選取 [ (無) ] 選項。此外,選擇 [更新] 和 [刪除] 索引標籤 ([無]) ,因為更新和刪除會透過 BLL 以程式設計方式執行。

確認 ObjectDataSource s INSERT、UPDATE 和 DELETE 索引標籤中的 Drop-Down 清單 設定 (為 [無])

圖 6:確認 ObjectDataSource s INSERT、UPDATE 和 DELETE 索引標籤標的 Drop-Down 清單 已設定為 [ (None) (按兩下即可檢視全大小映像)

設定 ObjectDataSource 之後,按兩下 [完成],返回 Designer。 如過去範例中所見,完成 ObjectDataSource 設定時,Visual Studio 會自動建立 ItemTemplate DropDownList 的 ,並顯示每個數據欄位。 將此值 ItemTemplate 取代為只顯示產品名稱與價格的 。 此外,將 RepeatColumns 屬性設定為 2。

注意

插入、更新和刪除數據 概觀中所述,使用 ObjectDataSource 修改數據時,我們的架構需要從 ObjectDataSource 的宣告式標記中移除 OldValuesParameterFormatString 屬性, (或將其重設為預設值, {0}) 。 不過,在本教學課程中,我們只使用 ObjectDataSource 來擷取數據。 因此,我們不需要修改 ObjectDataSource 的 OldValuesParameterFormatString 屬性值 (,但不會造成) 的傷害。

以自定義的 DataList 取代預設 DataList ItemTemplate 之後,頁面上的宣告式標記看起來應該類似下列內容:

<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
    DataSourceID="ObjectDataSource1" RepeatColumns="2">
    <ItemTemplate>
        <h5>
            <asp:Label runat="server" ID="ProductNameLabel"
                Text='<%# Eval("ProductName") %>'></asp:Label>
        </h5>
        Price: <asp:Label runat="server" ID="Label1"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
        <br />
        <br />
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    OldValuesParameterFormatString="original_{0}">
</asp:ObjectDataSource>

請花一點時間檢視瀏覽器的進度。 如圖 7 所示,DataList 會顯示兩個數據行中每個產品的產品名稱和單價。

產品名稱和價格會顯示在 Two-Column DataList 中

圖 7:產品名稱和價格會顯示在 Two-Column DataList 中, (按兩下即可檢視大小完整的影像)

注意

DataList 有一些更新和刪除程式所需的屬性,而且這些值會儲存在檢視狀態中。 因此,建置支援編輯或刪除數據的 DataList 時,必須啟用 DataList 的檢視狀態。

astute 讀取器可能會回想一下,在建立可編輯的 GridViews、DetailsViews 和 FormViews 時,我們能夠停用檢視狀態。 這是因為 ASP.NET 2.0 Web 控件可以包含 控件狀態,這是在檢視狀態等回傳之間保存的狀態,但視為必要。

在 GridView 中停用檢視狀態只會省略一般狀態資訊,但會維護控件狀態 (,其中包含編輯和刪除) 所需的狀態。 DataList 已在 ASP.NET 1.x 時間範圍內建立,不會利用控制狀態,因此必須啟用檢視狀態。 如需控件狀態用途的詳細資訊,以及其與檢視狀態有何不同,請參閱 控件狀態與 檢視狀態。

步驟 4:新增編輯使用者介面

GridView 控件是由一組字段所組成, (BoundFields、CheckBoxFields、TemplateFields 等等) 。 這些欄位可以根據其模式來調整其轉譯的標記。 例如,在只讀模式中時,BoundField 會將其數據域值顯示為文字;在編輯模式中時,它會轉譯 TextBox Web 控件,其 Text 屬性會指派數據域值。

另一方面,DataList 會使用範本轉譯其專案。 唯讀專案會使用 轉譯, ItemTemplate 而編輯模式中的專案則會透過 EditItemTemplate轉譯。 此時,我們的 DataList 只有 ItemTemplate。 若要支援專案層級編輯功能,我們需要新增 EditItemTemplate ,其中包含要針對可編輯項目顯示的標記。 在本教學課程中,我們將使用 TextBox Web 控件來編輯產品名稱和單價。

EditItemTemplate您可以從 DataList 的智慧標記) 選取 [編輯範本] 選項,以宣告方式或透過 Designer (來建立 。 若要使用 [編輯範本] 選項,請先按兩下智慧標記中的 [編輯範本] 連結,然後從下拉式清單中選取 EditItemTemplate 專案。

選擇使用 DataList s EditItemTemplate

圖 8:選擇使用 DataList s EditItemTemplate (按兩下以檢視大小完整的影像)

接下來,輸入產品名稱: 和 Price: ,然後將兩個 TextBox 控件從 [工具箱] 拖曳至 EditItemTemplate Designer 上的介面。 將 TextBoxes ID 屬性設定為 ProductNameUnitPrice

為產品名稱和價格新增 TextBox

圖 9:針對產品名稱和價格新增 TextBox (按兩下即可檢視大小完整的影像)

我們需要將對應的產品數據域值系結至 Text 兩個 TextBox 的屬性。 從 TextBoxes 智慧標記中,按兩下 [編輯 DataBindings] 連結,然後將適當的數據欄位與 Text 屬性產生關聯,如圖 10 所示。

注意

將數據欄位系結 UnitPrice 至 price TextBox s Text 欄位時,您可以將它格式化為貨幣值 ({0:C}) 、一般數位 ({0:N}) ,或讓它保持未格式化。

將 ProductName 和 UnitPrice 數據欄位系結至 TextBox 的文字屬性

圖 10:將 ProductNameUnitPrice 數據欄位系結至 Text TextBoxes 的屬性

請注意,圖 10 中的 [編輯 DataBindings] 對話框 如何不包含 在 GridView 或 DetailsView 中編輯 TemplateField 時出現的雙向數據系結複選框,或 FormView 中的範本。 雙向數據系結功能允許在輸入 Web 控制項中輸入的值自動指派給對應的 ObjectDataSource s InsertParametersUpdateParameters 插入或更新數據時。 DataList 不支援雙向數據系結,因為我們稍後會在本教學課程中看到,在使用者進行變更並準備好更新數據之後,我們必須以程序設計方式存取這些 TextBoxes Text 屬性,並將其值傳入 類別中的ProductsBLL適當UpdateProduct方法。

最後,我們需要將 [更新] 和 [取消] 按鈕新增至 EditItemTemplate。 如我們在 主復本/詳細數據使用具有詳細數據清單的主記錄專案符號列表 教學課程中所見,當按鈕、LinkButton 或 ImageButton CommandName 設定其屬性是從 Repeater 或 DataList 內按兩下時,就會引發 Repeater 或 DataList s ItemCommand 事件。 針對 DataList,如果 CommandName 屬性設定為特定值,也會引發額外的事件。 特殊 CommandName 屬性值包括下列專案:

  • Cancel 會 CancelCommand 引發事件
  • Edit 會 EditCommand 引發事件
  • Update 會 UpdateCommand 引發事件

請記住,除了 事件之外ItemCommand,還會引發這些事件。

將 新增至 EditItemTemplate 兩個 Button Web 控制項,其中一個設定為 [更新],另一個 CommandName 設定為 [取消]。 新增這兩個 Button Web 控制件之後,Designer 看起來應該類似下列內容:

顯示 DataList EditItemTemplate 的螢幕快照,其中已新增 [更新] 和 [取消] 按鈕。

圖 11:將 [更新] 和 [取消] 按鈕新增至 EditItemTemplate (按兩下以檢視大小完整的映像)

EditItemTemplate完成 DataList 的宣告式標記看起來應該類似下列內容:

<asp:DataList ID="DataList1" runat="server" DataKeyField="ProductID"
    DataSourceID="ObjectDataSource1" RepeatColumns="2">
    <ItemTemplate>
        <h5>
            <asp:Label runat="server" ID="ProductNameLabel"
                Text='<%# Eval("ProductName") %>' />
        </h5>
        Price: <asp:Label runat="server" ID="Label1"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
        <br />
        <br />
    </ItemTemplate>
    <EditItemTemplate>
        Product name:
            <asp:TextBox ID="ProductName" runat="server"
                Text='<%# Eval("ProductName") %>' /><br />
        Price:
            <asp:TextBox ID="UnitPrice" runat="server"
                Text='<%# Eval("UnitPrice", "{0:C}") %>' /><br />
        <br />
        <asp:Button ID="UpdateProduct" runat="server"
            CommandName="Update" Text="Update" /> 
        <asp:Button ID="CancelUpdate" runat="server"
            CommandName="Cancel" Text="Cancel" />
    </EditItemTemplate>
</asp:DataList>

步驟 5:新增管子以進入編輯模式

此時,DataList 已透過其 EditItemTemplate定義編輯介面;不過,目前沒有任何方法可讓使用者瀏覽我們的頁面,指出他想要編輯產品資訊。 我們需要將 [編輯] 按鈕新增至按兩下時的每個產品,以編輯模式呈現該 DataList 專案。 首先,透過 Designer 或宣告方式,將 [編輯] 按鈕新增至 ItemTemplate。 請務必將 [編輯] 按鈕的 CommandName 屬性設定為 [編輯]。

新增此 [編輯] 按鈕之後,請花點時間透過瀏覽器檢視頁面。 此外,每個產品清單都應該包含 [編輯] 按鈕。

顯示已新增 [編輯] 按鈕之 DataList EditItemTemplate 的螢幕快照。

圖 12:將 [更新] 和 [取消] 按鈕新增至 EditItemTemplate ([ 按兩下] 以檢視大小完整的映像)

按兩下按鈕會導致回傳,但 不會 將產品清單帶入編輯模式。 若要讓產品成為可編輯的,我們需要:

  1. 將 DataList s EditItemIndex 屬性 設定為剛按下 [編輯] 按鈕的 DataListItem 索引。
  2. 將數據重新系結至 DataList。 重新轉譯 DataList 時, DataListItemItemIndex 對應至 DataList 的 EditItemIndex 會使用其 EditItemTemplate轉譯。

由於按兩下 [編輯] 按鈕時會引發 DataList s EditCommand 事件,因此請使用下列程式代碼建立 EditCommand 事件處理程式:

protected void DataList1_EditCommand(object source, DataListCommandEventArgs e)
{
    // Set the DataList's EditItemIndex property to the
    // index of the DataListItem that was clicked
    DataList1.EditItemIndex = e.Item.ItemIndex;
    // Rebind the data to the DataList
    DataList1.DataBind();
}

EditCommand事件處理程式會以類型DataListCommandEventArgs為其第二個輸入參數的 對象傳遞,其中包含已按兩下其 [編輯] 按鈕 (e.Item) 的參考DataListItem。 事件處理程式會先將 DataList s EditItemIndex 設定為 ItemIndexDataListItem 編輯的 ,然後呼叫 DataList s DataBind() 方法,將數據重新繫結至 DataList。

新增此事件處理程式之後,請重新瀏覽瀏覽器中的頁面。 按兩下 [編輯] 按鈕現在可讓按下的產品可編輯 (請參閱圖 13) 。

按兩下 [編輯] 按鈕可讓產品編輯

圖 13:按兩下 [編輯] 按鈕可讓產品編輯 (按下即可檢視全大小影像)

步驟 6:儲存用戶變更

按兩下編輯的產品 [更新] 或 [取消] 按鈕此時不會執行任何動作;若要新增這項功能,我們需要為 DataList 和 UpdateCommandCancelCommand 事件建立事件處理程式。 首先, CancelCommand 建立事件處理程式,這會在按兩下編輯的產品 [取消] 按鈕時執行,並且工作是將DataList傳回至其預先編輯狀態。

若要讓 DataList 以唯讀模式呈現其所有項目,我們需要:

  1. 將 DataList s EditItemIndex 屬性 設定為不存在 DataListItem 索引的索引。 -1 是安全的選擇,因為索引 DataListItem0開始。
  2. 將數據重新系結至 DataList。 因為沒有 DataListItemItemIndex 對應到 DataList s EditItemIndex,所以整個 DataList 將會以唯讀模式呈現。

您可以使用下列事件處理程式程式代碼來完成這些步驟:

protected void DataList1_CancelCommand(object source, DataListCommandEventArgs e)
{
    // Set the DataList's EditItemIndex property to -1
    DataList1.EditItemIndex = -1;
    // Rebind the data to the DataList
    DataList1.DataBind();
}

此外,按兩下 [取消] 按鈕會將DataList傳回至其預先編輯狀態。

我們需要完成的最後一個事件處理程式是 UpdateCommand 事件處理程式。 此事件處理程式需要:

  1. 以程式設計方式存取使用者輸入的產品名稱和價格,以及編輯的產品 。ProductID
  2. 藉由在類別中ProductsBLL呼叫適當的UpdateProduct多載來起始更新程式。
  3. 將 DataList s EditItemIndex 屬性 設定為不存在 DataListItem 索引的索引。 -1 是安全的選擇,因為索引 DataListItem0開始。
  4. 將數據重新系結至 DataList。 因為沒有 DataListItemItemIndex 對應到 DataList s EditItemIndex,所以整個 DataList 將會以唯讀模式呈現。

步驟 1 和 2 負責儲存用戶的變更;步驟 3 和 4 會在儲存變更之後,將 DataList 傳回至其預先編輯狀態,而且與事件處理程式中 CancelCommand 執行的步驟相同。

若要取得更新的產品名稱和價格,我們必須使用 FindControl 方法來以程式設計方式參考 中的 EditItemTemplateTextBox Web 控制件。 我們也需要取得編輯的產品 ProductID 值。 當我們一開始將 ObjectDataSource 系結至 DataList 時,Visual Studio 會將 DataList s DataKeyField 屬性指派給數據源的主鍵值, (ProductID) 。 然後,您可以從 DataList 集合 DataKeys 擷取此值。 花點時間確定 DataKeyField 屬性確實設定為 ProductID

下列程式代碼會實作四個步驟:

protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
{
    // Read in the ProductID from the DataKeys collection
    int productID = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex]);
    // Read in the product name and price values
    TextBox productName = (TextBox)e.Item.FindControl("ProductName");
    TextBox unitPrice = (TextBox)e.Item.FindControl("UnitPrice");
    string productNameValue = null;
    if (productName.Text.Trim().Length > 0)
        productNameValue = productName.Text.Trim();
    decimal? unitPriceValue = null;
    if (unitPrice.Text.Trim().Length > 0)
        unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(),
            System.Globalization.NumberStyles.Currency);
    // Call the ProductsBLL's UpdateProduct method...
    ProductsBLL productsAPI = new ProductsBLL();
    productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID);
    // Revert the DataList back to its pre-editing state
    DataList1.EditItemIndex = -1;
    DataList1.DataBind();
}

事件處理程式會從集合讀取已編輯的產品ProductIDDataKeys開始。 接下來,會參考 中的EditItemTemplate兩個 TextBox,以及儲存在局部變數 productNameValueunitPriceValueText 中的屬性。 Decimal.Parse()我們使用 方法從 UnitPrice TextBox 讀取值,如此一來,如果輸入的值具有貨幣符號,它仍然可以正確地轉換成Decimal值。

注意

如果 TextBoxes Text 屬性已指定值,則 來自 ProductNameUnitPrice TextBoxes 的值只會指派給 productNameValue 和 unitPriceValue 變數。 否則,會針對變數使用 值 Nothing ,其效果是使用資料庫 NULL 值來更新數據。 也就是說,我們的程式代碼會將空字串轉換成資料庫 NULL 值,這是 GridView、DetailsView 和 FormView 控件中編輯介面的默認行為。

讀取值之後,會 ProductsBLL 呼叫 類別 s UpdateProduct 方法,並傳入產品名稱、價格和 ProductID。 事件處理程式會使用與事件處理程式完全相同的邏輯,將 DataList 傳回至其預先編輯狀態來完成 CancelCommand

EditCommand當、 CancelCommandUpdateCommand 事件處理程式完成時,訪客可以編輯產品的名稱和價格。 圖 14-16 顯示此編輯工作流程的運作情形。

第一次瀏覽頁面時,所有產品都處於 Read-Only 模式

圖 14:第一次瀏覽頁面時,所有產品都處於 Read-Only 模式, (按兩下即可檢視全尺寸影像)

若要更新產品名稱或價格,請按兩下 [編輯] 按鈕

圖 15:若要更新產品名稱或價格,請按兩下 [編輯] 按鈕 (按兩下以檢視大小完整的影像)

變更值之後,按兩下 [更新] 傳回 Read-Only 模式

圖 16:變更值之後,按兩下 [更新] 傳回 Read-Only 模式 (按兩下即可檢視大小完整的映像)

步驟 7:新增刪除功能

將刪除功能新增至 DataList 的步驟類似於新增編輯功能的步驟。 簡單來說,我們需要在按兩下時,將 [刪除] 按鈕新增至 ItemTemplate 該按鈕:

  1. 透過集合讀取對應產品的 ProductIDDataKeys
  2. 呼叫 類別 s DeleteProduct 方法,ProductsBLL以執行刪除。
  3. 將數據重新系結至 DataList。

讓我們從將 [刪除] 按鈕新增至 ItemTemplate開始。

按兩下時, CommandName [按鈕] 為 [編輯]、[更新] 或 [取消] 會引發DataList s ItemCommand 事件,例如,使用 [編輯 EditCommand ] 時,也會引發其他事件 (,以及) 。 同樣地,DataList CommandName 中設定屬性為 Delete 的任何 Button、LinkButton 或 ImageButton 都會 DeleteCommand 引發事件 (以及 ItemCommand) 。

在 的 ItemTemplate[編輯] 按鈕旁新增 [刪除] 按鈕,並將其 CommandName 屬性設定為Delete。 新增此 Button 控件之後,DataList 的 ItemTemplate 宣告式語法看起來應該像這樣:

<ItemTemplate>
    <h5>
        <asp:Label runat="server" ID="ProductNameLabel"
            Text='<%# Eval("ProductName") %>' />
    </h5>
    Price: <asp:Label runat="server" ID="Label1"
                Text='<%# Eval("UnitPrice", "{0:C}") %>' />
    <br />
    <asp:Button runat="server" id="EditProduct" CommandName="Edit"
        Text="Edit" />
     
    <asp:Button runat="server" id="DeleteProduct" CommandName="Delete"
        Text="Delete" />
    <br />
    <br />
</ItemTemplate>

接下來,使用下列程序代碼,為 DataList s DeleteCommand 事件建立事件處理程式:

protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
{
    // Read in the ProductID from the DataKeys collection
    int productID = Convert.ToInt32(DataList1.DataKeys[e.Item.ItemIndex]);
    // Delete the data
    ProductsBLL productsAPI = new ProductsBLL();
    productsAPI.DeleteProduct(productID);
    // Rebind the data to the DataList
    DataList1.DataBind();
}

按兩下 [刪除] 按鈕會導致回傳並引發DataList s DeleteCommand 事件。 在事件處理程式中,按兩下的產品 ProductID 值是從集合存取 DataKeys 。 接下來,呼叫 類別 s DeleteProduct 方法會刪除ProductsBLL產品。

刪除產品之後,請務必將數據重新系結至 DataList (DataList1.DataBind()) ,否則 DataList 會繼續顯示剛刪除的產品。

摘要

雖然 DataList 缺少點,但按下 GridView 所享受的編輯和刪除支援,但可以透過一些簡短的程式代碼加以增強,以包含這些功能。 在本教學課程中,我們已瞭解如何建立可刪除且可編輯其名稱和價格的兩欄產品清單。 新增編輯和刪除支援是包括 和 EditItemTemplateItemTemplate適當的 Web 控制項、建立對應的事件處理程式、讀取使用者輸入和主鍵值,以及與商業規則層互動。

雖然我們已將基本編輯和刪除功能新增至 DataList,但缺少更進階的功能。 例如,沒有輸入欄位驗證 - 如果使用者輸入太昂貴的價格,則嘗試將太昂貴轉換成 Decimal時,將會擲回Decimal.Parse例外狀況。 同樣地,如果在商業規則或數據存取層更新數據時發生問題,使用者就會看到標準錯誤畫面。 若未在 [刪除] 按鈕上進行任何確認,不小心刪除產品可能也一樣。

在未來的教學課程中,我們將瞭解如何改善編輯用戶體驗。

快樂的程序設計!

關於作者

Scott Mitchell 是七份 ASP/ASP.NET 書籍的作者,以及 1998 年以來與 Microsoft Web 技術合作的 4GuysFromRolla.com 作者。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格來連線到 ,您可以在 找到http://ScottOnWriting.NET

特別感謝

本教學課程系列是由許多實用的檢閱者檢閱。 本教學課程的首席檢閱者是 Zack Jones、Ken Pespisa 和 Randy Schmidt。 有興趣檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行 mitchell@4GuysFromRolla.com放在 。