共用方式為


在 DataList 中編輯和刪除數據的概觀 (VB)

由斯科特· 米切爾

下載 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,重複項控件缺少插入、更新或刪除的現用功能。 雖然可以新增這類功能,但 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.aspxEditDeleteDataList 資料夾中列出其區段中的教學課程。 回想一下, 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 中的數據:

  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 進行選取,但直接對 BLL 進行更新和刪除呼叫(例如選項 1)。 在我看來,透過直接與 BLL 互動來更新數據,會導致比指派 ObjectDataSource s UpdateParameters 並呼叫其 Update() 方法更容易閱讀的程序代碼。
  4. 透過多個 ObjectDataSource 使用宣告式 Means,上述三種方法都需要一點程式代碼。 如果您寧願繼續使用盡可能多的宣告式語法,最後一個選項是在頁面上包含多個 ObjectDataSources。 第一個 ObjectDataSource 會從 BLL 擷取數據,並將它系結至 DataList。 若要更新,會新增另一個 ObjectDataSource,但會直接在 DataList s EditItemTemplate中新增 。 若要包含刪除支援,還需要在 中 ItemTemplate新增另一個 ObjectDataSource。 透過這種方法,這些內嵌的 ObjectDataSource 會使用 ControlParameters 宣告方式將 ObjectDataSource 參數係結至使用者輸入控件(而不必以程序設計方式在 DataList UpdateCommand 事件處理程式中指定它們)。 此方法仍然需要一些程式代碼,我們需要呼叫內嵌的 ObjectDataSource s 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 一樣,不是針對插入新數據而設計的;因此,從 [插入] 索引標籤的下拉式清單中選取 [無] 選項。此外,選擇 [更新] 和 [刪除] 索引標籤的 [無] ,因為更新和刪除將會透過 BLL 以程式設計方式執行。

確認 ObjectDataSource 中的下拉式清單 INSERT、UPDATE 和 DELETE 索引標籤已設定為 [無]

圖 6:確認 ObjectDataSource s INSERT、UPDATE 和 DELETE 索引標籤標的下拉式清單已設定為 [無] (按兩下以檢視完整大小的影像

設定 ObjectDataSource 之後,按兩下 [完成],返回設計工具。 如往範例所示,完成 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 會在兩個數據行中顯示每個產品的產品名稱和單價。

[產品名稱] 和 [價格] 會顯示在雙欄 DataList 中

圖 7:產品名稱和價格會顯示在雙欄資料清單中(按兩下以檢視完整大小的影像

注意

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

精明的讀取器可能會記得,在建立可編輯的 GridView、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 智慧標記中選取 [編輯範本] 選項)。 若要使用 [編輯範本] 選項,請先按兩下智慧標記中的 [編輯範本] 連結,然後從下拉式清單中選取 EditItemTemplate 專案。

選擇使用 DataList s EditItemTemplate

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

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

為產品名稱和價格新增 TextBox

圖 9:新增 [產品名稱] 和 [價格] 的 TextBox (單擊以檢視完整大小的影像

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

注意

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

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

圖 10:將 和 UnitPrice 數據欄位系結ProductNameText TextBoxes 的屬性

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

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

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

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

將 新增至 EditItemTemplate 兩個 Button Web 控制項,其中一個設定為 Update,另一 CommandName 個設定為 Cancel。 新增這兩個 Button Web 控制件之後,設計工具看起來應該如下所示:

顯示 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 專案。 首先,透過設計工具或以宣告方式將 [編輯] 按鈕新增至 ItemTemplate。 請務必將 [編輯] 按鈕的 CommandName 屬性設定為 [編輯]。

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

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

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

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

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

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

Protected Sub DataList1_EditCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.EditCommand
    ' 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()
End Sub

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

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

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

圖 13:按兩下 [編輯] 按鈕可編輯產品 (按兩下以檢視完整大小的影像

步驟 6:儲存用戶變更

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

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

  1. 將 DataList s EditItemIndex 屬性 設定為不存在 DataListItem 索引的索引。 -1 是安全的選擇,因為 DataListItem 索引從 開始 0
  2. 將數據重新系結至 DataList。 由於沒有 DataListItem ItemIndex es 對應至 DataList s EditItemIndex,因此整個 DataList 將會以唯讀模式轉譯。

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

Protected Sub DataList1_CancelCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.CancelCommand
    ' Set the DataList's EditItemIndex property to -1
    DataList1.EditItemIndex = -1
    ' Rebind the data to the DataList
    DataList1.DataBind()
End Sub

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

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

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

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

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

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

Protected Sub DataList1_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.UpdateCommand
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(DataList1.DataKeys(e.Item.ItemIndex))
    ' Read in the product name and price values
    Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
    Dim unitPrice As TextBox = CType(e.Item.FindControl("UnitPrice"), TextBox)
    Dim productNameValue As String = Nothing
    If productName.Text.Trim().Length > 0 Then
        productNameValue = productName.Text.Trim()
    End If
    Dim unitPriceValue As Nullable(Of Decimal) = Nothing
    If unitPrice.Text.Trim().Length > 0 Then
        unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(), NumberStyles.Currency)
    End If
    ' Call the ProductsBLL's UpdateProduct method...
    Dim productsAPI As New ProductsBLL()
    productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID)
    ' Revert the DataList back to its pre-editing state
    DataList1.EditItemIndex = -1
    DataList1.DataBind()
End Sub

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

注意

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

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

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

第一次瀏覽頁面時,所有產品都處於只讀模式

圖 14:第一次瀏覽頁面時,所有產品都處於只讀模式(按兩下以檢視完整大小的影像

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

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

變更值之後,按兩下 [更新] 傳回唯讀模式

圖 16:變更值之後,按兩下 [更新] 傳回唯讀模式 (按一下以檢視完整大小的影像

步驟 7:新增刪除功能

將刪除功能新增至 DataList 的步驟與新增編輯功能的步驟類似。 簡言之,我們需要在按兩下時,將 [刪除] 按鈕新增至 ItemTemplate

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

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

按兩下時,即為 [編輯]、[更新] 或 [取消] 的Button CommandName 會引發DataList事件 ItemCommand 以及其他事件(例如,使用 [編輯 EditCommand ] 時也會引發事件)。 同樣地,DataList 中任何 Button、LinkButton 或 ImageButton 的 CommandName 屬性設定為 Delete,都會引發 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 Sub DataList1_DeleteCommand(source As Object, e As DataListCommandEventArgs) _
    Handles DataList1.DeleteCommand
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(DataList1.DataKeys(e.Item.ItemIndex))
    ' Delete the data
    Dim productsAPI As New ProductsBLL()
    productsAPI.DeleteProduct(productID)
    ' Rebind the data to the DataList
    DataList1.DataBind()
End Sub

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

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

摘要

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

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

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

快樂的程序設計!

關於作者

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

特別感謝

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