檢查與插入、更新和刪除建立關聯的事件 (C#)
在本教學課程中,我們將探討如何使用在 ASP.NET 數據 Web 控件的插入、更新或刪除作業之前、期間和之後發生的事件。 我們也會瞭解如何自定義編輯介面,只更新產品欄位的子集。
簡介
使用 GridView、DetailsView 或 FormView 控件的內建插入、編輯或刪除功能時,當使用者完成新增記錄或刪除現有記錄的程式時,會進行各種步驟。 如 我們在上一個教學課程中所討論,在 GridView 中編輯數據列時,[編輯] 按鈕會由 [更新] 和 [取消] 按鈕取代,而 BoundFields 會變成 TextBoxes。 使用者更新數據並按兩下列步驟:
- GridView 會使用
DataKeyNames
編輯記錄的唯一識別欄位填入其 ObjectDataSourceUpdateParameters
的 , (屬性) (,以及使用者輸入的值) - GridView 會叫用其 ObjectDataSource 的
Update()
方法,接著會在上一個教學課程中叫用基礎物件 (ProductsDAL.UpdateProduct
的適當方法) - 現在包含更新變更的基礎數據會重新系結至 GridView
在這個步驟序列期間,會引發一些事件,讓我們能夠建立事件處理程序,視需要新增自定義邏輯。 例如,在步驟 1 之前,GridView 的事件 RowUpdating
會引發。 此時,如果發生驗證錯誤,我們可以取消更新要求。 Update()
叫用 方法時,ObjectDataSource 的事件Updating
會引發,提供新增或自定義任何 UpdateParameters
值的機會。 在 ObjectDataSource 的基礎物件方法完成執行之後,就會引發 ObjectDataSource 的事件 Updated
。 事件的事件處理程式 Updated
可以檢查更新作業的詳細數據,例如受影響的數據列數目,以及是否發生例外狀況。 最後,在步驟 2 之後,GridView 的事件 RowUpdated
會引發;此事件的事件處理程式可以檢查剛執行之更新作業的其他資訊。
圖 1 描述更新 GridView 時的這一系列事件和步驟。 圖 1 中的事件模式不是使用 GridView 進行更新的唯一專案。 在 GridView、DetailsView 或 FormView 中插入、更新或刪除數據,會針對數據 Web 控件和 ObjectDataSource,預先和後置事件順序進行預先和後置事件。
圖 1:更新 GridView 中的數據時引發一系列的前置和後置事件 (按兩下以檢視大小完整的影像)
在本教學課程中,我們將探討如何使用這些事件來擴充內建插入、更新和刪除 ASP.NET 數據 Web 控件的功能。 我們也會瞭解如何自定義編輯介面,只更新產品欄位的子集。
步驟 1:更新產品的ProductName
和UnitPrice
欄位
在上一個教學課程的編輯介面中 , 所有不是只讀的產品欄位都必須包含。 如果我們要從 GridView 移除欄位, 例如 QuantityPerUnit
- 更新資料時,數據 Web 控制件不會設定 ObjectDataSource QuantityPerUnit
UpdateParameters
的值。 ObjectDataSource 接著會將值UpdateProduct
傳入 null
Business Logic Layer (BLL) 方法,這會將編輯的資料庫記錄數據QuantityPerUnit
行變更為NULL
值。 同樣地,如果從編輯介面中移除必要的欄位, ProductName
更新將會失敗,並顯示「數據行 』ProductName' 不允許 Null」例外狀況。 此行為的原因是 ObjectDataSource 已設定為呼叫 ProductsBLL
類別的 UpdateProduct
方法,這預期每個產品欄位都有輸入參數。 因此,ObjectDataSource 的 UpdateParameters
集合包含每個方法輸入參數的參數。
如果我們想要提供可讓使用者只更新字段子集的數據 Web 控件,則我們需要以程式設計方式設定 ObjectDataSource Updating
事件處理程式中的遺漏UpdateParameters
值,或建立並呼叫只預期字段子集的 BLL 方法。 讓我們來探索後者的方法。
具體而言,讓我們建立一個頁面,只 ProductName
顯示可編輯 GridView 中的 和 UnitPrice
字段。 此 GridView 的編輯介面只允許使用者更新兩個顯示的欄位與 ProductName
UnitPrice
。 由於此編輯介面只提供產品字段的子集,因此我們需要建立 ObjectDataSource 來使用現有的 BLL UpdateProduct
方法,並在其 Updating
事件處理程式中以程式設計方式設定遺漏的產品域值,或者我們需要建立新的 BLL 方法,預期只有 GridView 中定義的字段子集。 在本教學課程中,讓我們使用後者選項並建立 方法的多 UpdateProduct
載,其中一個只接受三個輸入參數: productName
、 unitPrice
和 productID
:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, decimal? unitPrice, int productID)
{
Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
if (products.Count == 0)
// no matching record found, return false
return false;
Northwind.ProductsRow product = products[0];
product.ProductName = productName;
if (unitPrice == null) product.SetUnitPriceNull();
else product.UnitPrice = unitPrice.Value;
// Update the product record
int rowsAffected = Adapter.Update(product);
// Return true if precisely one row was updated, otherwise false
return rowsAffected == 1;
}
如同原始 UpdateProduct
方法,此多載一開始會檢查資料庫中是否有具有指定 ProductID
的產品。 如果沒有,則會傳 false
回 ,表示更新產品資訊的要求失敗。 否則,它會據以更新現有的產品記錄 ProductName
和 UnitPrice
字段,並藉由呼叫 TableAdapter 的 Update()
方法來認可更新,並 ProductsRow
傳入 實例。
除了 我們的 ProductsBLL
類別之外,還準備好建立簡化的 GridView 介面。 開啟資料夾中的 EditInsertDelete
,DataModificationEvents.aspx
並將 GridView 新增至頁面。 建立新的 ObjectDataSource,並將其設定為使用 ProductsBLL
類別與其Select()
方法對應,GetProducts
以及其Update()
方法對應至UpdateProduct
只接受 、 unitPrice
和 productID
輸入參數的多productName
載。 圖 2 顯示將 ObjectDataSource Update()
的 方法對應至 ProductsBLL
類別的新 UpdateProduct
方法多載時,建立數據源精靈。
圖 2:將 ObjectDataSource 的 Update()
方法對應至 [新增 UpdateProduct
多載] (按兩下即可檢視完整大小的影像)
由於我們的範例一開始只需要編輯數據的能力,但不需要插入或刪除記錄,請花一點時間明確地指出 ObjectDataSource Insert()
的 和 Delete()
方法不應透過移至 INSERT 和 DELETE 索引標籤並選擇 ([無]) 從下拉式清單中對應至任何 ProductsBLL
類別的方法。
圖 3:從 [插入] 和 [刪除] 索引標籤的 [Drop-Down 列表中選擇 ([無) ], (按兩下即可檢視大小完整的影像)
完成此精靈之後,請核取 GridView 智慧標記中的 [啟用編輯] 複選框。
完成 [建立數據源精靈] 並系結至 GridView 之後,Visual Studio 已建立這兩個控件的宣告式語法。 移至 [來源] 檢視以檢查 ObjectDataSource 的宣告式標記,如下所示:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
由於 ObjectDataSource 的 Insert()
和 Delete()
方法沒有對應,因此沒有 InsertParameters
或 DeleteParameters
區段。 此外,由於 Update()
方法會對應至 UpdateProduct
只接受三個輸入參數的方法多載,因此區 UpdateParameters
段只有三 Parameter
個實例。
請注意,ObjectDataSource 的 OldValuesParameterFormatString
屬性設定為 original_{0}
。 使用 [設定數據源精靈] 時,Visual Studio 會自動設定此屬性。 不過,由於 BLL 方法不會預期原始 ProductID
值傳入,請從 ObjectDataSource 的宣告式語法完全移除此屬性指派。
注意
如果您只是清除 OldValuesParameterFormatString
[設計] 檢視中 屬性視窗 的屬性值,屬性仍會存在於宣告式語法中,但會設定為空字串。 請完全從宣告式語法中移除 屬性,或從 屬性視窗 將值設定為預設值 {0}
。
雖然 ObjectDataSource 只針對產品名稱、價格和標識碼具有 UpdateParameters
,但 Visual Studio 已在 GridView 中針對每個產品的欄位新增 BoundField 或 CheckBoxField。
圖 4:GridView 包含每個產品欄位的 BoundField 或 CheckBoxField, (按兩下即可檢視完整大小的影像)
當使用者編輯產品並按兩下其 [更新] 按鈕時,GridView 會列舉不是只讀的欄位。 然後,它會將 ObjectDataSource UpdateParameters
集合中對應參數的值設定為使用者輸入的值。 如果沒有對應的參數,GridView 會將一個參數新增至集合。 因此,如果我們的 GridView 包含所有產品欄位的 BoundFields 和 CheckBoxFields,ObjectDataSource 最終會叫 UpdateProduct
用所有參數中的多載,儘管 ObjectDataSource 的宣告標記只指定三個輸入參數 (請參閱圖 5) 。 同樣地,如果 GridView 中有一些未對應至多載輸入參數 UpdateProduct
的非只讀產品欄位群組,則會在嘗試更新時引發例外狀況。
圖 5:GridView 會將參數新增至 ObjectDataSource 的 UpdateParameters
集合 (按兩下即可檢視大小完整的影像)
為了確保 ObjectDataSource 會叫 UpdateProduct
用只接受產品名稱、價格和標識碼的多載,我們必須將 GridView 限制為只有 ProductName
和 UnitPrice
的可編輯欄位。 這可以藉由移除其他 BoundFields 和 CheckBoxFields、將其他欄位的 ReadOnly
屬性設定為 true
或兩者的組合來完成。 在本教學課程中,我們只要移除 和 UnitPrice
BoundFields 以外的ProductName
所有 GridView 欄位,GridView 的宣告式標記看起來會像這樣:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
雖然多 UpdateProduct
載需要三個輸入參數,但我們在 GridView 中只有兩個 BoundField。 這是因為 productID
輸入參數是主鍵值,並透過已編輯數據列的 DataKeyNames
屬性值傳入。
我們的 GridView 以及 UpdateProduct
多載可讓使用者只編輯產品的名稱和價格,而不會遺失任何其他產品字段。
圖 6:介面允許僅編輯產品名稱和價格 (按兩下即可檢視完整大小的影像)
注意
如上一個教學課程所述,在預設行為) (啟用 GridView 檢視狀態非常重要。 如果您將 GridView 的 EnableViewState
屬性設定為 false
,則會執行不小心刪除或編輯記錄並行用戶的風險。
改善格式設定UnitPrice
雖然圖 6 所示的 GridView 範例運作正常, UnitPrice
但字段完全不會格式化,因此價格顯示缺少任何貨幣符號,而且有四個小數位數。 若要套用不可編輯資料列的貨幣格式設定,只要將 UnitPrice
BoundField 的 DataFormatString
屬性設定為 {0:c}
,並將其 HtmlEncode
屬性設定為 false
。
圖 7:設定 UnitPrice
的 DataFormatString
和 HtmlEncode
屬性[據 (按兩下以檢視完整大小的影像)
透過這項變更,不可編輯的數據列會將價格格式化為貨幣;不過,已編輯的數據列仍然會顯示沒有貨幣符號的值,以及四個小數位數。
圖 8:不可編輯的數據列現在會格式化為貨幣值, (按兩下即可檢視完整大小的影像)
屬性中指定的 DataFormatString
格式設定指令可以套用至編輯介面,方法是將 BoundField 的 ApplyFormatInEditMode
屬性設定為 true
(預設值為 false
) 。 請花點時間將這個屬性設定為 true
。
圖 9:將 BoundField 的 ApplyFormatInEditMode
屬性設定UnitPrice
為 true
(按兩下即可檢視完整大小的影像)
透過這項變更,編輯數據列中所顯示 的值 UnitPrice
也會格式化為貨幣。
圖 10:編輯的數據列 UnitPrice
值現在格式化為貨幣 (按兩下即可檢視大小完整的影像)
不過,在文字框中使用貨幣符號更新產品,例如 $19.00 會擲回 FormatException
。 當 GridView 嘗試將使用者提供的值指派給 ObjectDataSource 的UpdateParameters
集合時,無法將字串 “$19.00” decimal
轉換成UnitPrice
參數所需的 , (請參閱圖 11) 。 若要解決此問題,我們可以為 GridView 的事件RowUpdating
建立事件處理程式,並讓它剖析為貨幣格式decimal
的使用者UnitPrice
。
GridView 的事件 RowUpdating
接受其第二個參數 GridViewUpdateEventArgs 類型的物件,其中包含字典做為其其中一個 NewValues
屬性,其中保存可供指派給 ObjectDataSource UpdateParameters
集合的使用者提供值。 我們可以使用貨幣格式與事件處理程式中的下列程式代碼RowUpdating
行,以剖析的十進位值覆寫集合中的NewValues
現有UnitPrice
值:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
e.NewValues["UnitPrice"] =
decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
如果使用者已提供 UnitPrice
值 (,例如 “$19.00”) ,則會以 Decimal.Parse 計算的十進位值覆寫此值,將值剖析為貨幣。 這會正確剖析任何貨幣符號、逗號、小數點等事件中的十進制數,並使用 System.Globalization 命名空間中的 NumberStyles 列舉。
圖 11 顯示使用者提供 UnitPrice
中貨幣符號所造成的兩個問題,以及 GridView RowUpdating
事件處理程式如何用來正確剖析這類輸入。
圖 11:編輯的數據列 UnitPrice
值現在格式化為貨幣 (按兩下即可檢視大小完整的影像)
步驟 2:禁止NULL UnitPrices
當資料庫設定為允許NULL
數據表數據UnitPrice
行中的Products
值時,我們可能會想要防止使用者流覽此特定頁面來指定NULL
UnitPrice
值。 也就是說,如果使用者在編輯產品數據列時無法輸入 UnitPrice
值,而不是將結果儲存到我們想要顯示訊息給使用者,告知使用者透過此頁面,任何已編輯的產品都必須有指定的價格。
GridViewUpdateEventArgs
傳遞至 GridView 事件處理程式的物件RowUpdating
包含Cancel
屬性,如果設定為 true
,則會終止更新程式。 讓我們擴充RowUpdating
事件處理程式來設定 true
e.Cancel
為 ,並顯示一則訊息,說明集合中的NewValues
值是否UnitPrice
為 null
。
首先,將標籤 Web 控件新增至名為 MustProvideUnitPriceMessage
的頁面。 如果使用者在更新產品時無法指定 UnitPrice
值,就會顯示此標籤控件。 將標籤的 Text
屬性設定為「您必須提供產品的價格」。我也會使用下列定義,在 名為 Warning
中Styles.css
建立新的 CSS 類別:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
最後,將 Label 的 CssClass
屬性設定為 Warning
。 此時,Designer 應該會在 GridView 上方的紅色、粗體、斜體、超大型字型大小中顯示警告訊息,如圖 12 所示。
圖 12:在 GridView 上方新增標籤 (按一下以檢視大小完整的影像)
根據預設,應該隱藏此標籤,因此請在事件處理程式中將其 Visible
屬性設定為 false
Page_Load
:
protected void Page_Load(object sender, EventArgs e)
{
MustProvideUnitPriceMessage.Visible = false;
}
如果用戶嘗試在不指定 UnitPrice
的情況下更新產品,我們想要取消更新並顯示警告標籤。 增強 GridView 的 RowUpdating
事件處理程式,如下所示:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
{
e.NewValues["UnitPrice"] =
decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
else
{
// Show the Label
MustProvideUnitPriceMessage.Visible = true;
// Cancel the update
e.Cancel = true;
}
}
如果使用者嘗試儲存產品而不指定價格,則會取消更新,並顯示有用的訊息。 雖然資料庫 (和商業規則) 允許 NULL
UnitPrice
,但此特定 ASP.NET 頁面則不允許。
圖 13:用戶無法保留 UnitPrice
空白 (按兩下即可檢視完整大小的影像)
到目前為止,我們已瞭解如何使用 GridView 的事件 RowUpdating
,以程式設計方式改變指派給 ObjectDataSource 集合的參數 UpdateParameters
值,以及如何完全取消更新程式。 這些概念會繼續至 DetailsView 和 FormView 控件,也適用於插入和刪除。
這些工作也可以透過其 Inserting
、 Updating
和 Deleting
事件的事件處理程式,在 ObjectDataSource 層級完成。 這些事件會在叫用基礎對象的相關聯方法之前引發,並提供最後一個機會來修改輸入參數集合,或直接取消作業。 這三個事件的事件處理程式會傳遞 ObjectDataSourceMethodEventArgs 類型的物件,其具有兩個感興趣的屬性:
- 取消,如果設定為
true
,則會取消正在執行的作業 - InputParameters,這是 、
UpdateParameters
或DeleteParameters
的集合InsertParameters
,視事件處理程式是否為Inserting
、Updating
或Deleting
事件而定
為了說明如何在 ObjectDataSource 層級使用參數值,讓我們在頁面中加入 DetailsView,讓用戶能夠新增產品。 此 DetailsView 將用來提供介面,以便快速將新產品新增至資料庫。 若要在新增產品時保持一致的使用者介面,讓我們允許使用者只輸入 和 UnitPrice
字段的值ProductName
。 根據預設,DetailsView 插入介面中未提供的值會設定為 NULL
資料庫值。 不過,我們可以使用 ObjectDataSource 的事件 Inserting
來插入不同的預設值,因為我們很快就會看到。
步驟 3:提供介面以新增產品
將 DetailsView 從 [工具箱] 拖曳至 GridView 上方的 Designer、清除其 Height
和 Width
屬性,然後將它系結至頁面上已經存在的 ObjectDataSource。 這會為每個產品的欄位新增 BoundField 或 CheckBoxField。 由於我們想要使用此 DetailsView 來新增產品,因此我們需要從智慧標記中檢查 [啟用插入] 選項;不過,沒有這類選項,因為 ObjectDataSource 的 Insert()
方法並未對應至 類別中的 ProductsBLL
方法, (回想一下,我們在設定數據源時將此對應設定為 (None) 請參閱圖 3) 。
若要設定 ObjectDataSource,請從其智慧標記中選取 [設定數據源] 鏈接,啟動精靈。 第一個畫面可讓您變更 ObjectDataSource 所系結的基礎物件;設定為 ProductsBLL
。 下一個畫面會列出從 ObjectDataSource 方法到基礎對象的對應。 即使我們明確指出 Insert()
和 Delete()
方法不應該對應至任何方法,但如果您移至 INSERT 和 DELETE 索引標籤,您會看到對應存在。 這是因為ProductsBLL
的 AddProduct
和 DeleteProduct
方法會分別使用 DataObjectMethodAttribute
屬性來指出它們是 和Delete()
的預設方法Insert()
。 因此,除非您明確指定一些其他值,否則 ObjectDataSource 精靈會在每次執行精靈時選取這些精靈。
Insert()
讓方法指向 方法AddProduct
,但再次將 DELETE 索引標籤的下拉式清單設定為 ([無]) 。
圖 14:將 INSERT 索引標籤的 [Drop-Down 列表] 設定為 AddProduct
[方法] (按兩下即可檢視完整大小的影像)
圖 15:將 [刪除] 索引標籤的 [Drop-Down 列表] 設定為 [無] () (按兩下即可檢視大小完整的影像)
進行這些變更之後,ObjectDataSource 的宣告式語法將會展開以包含 InsertParameters
集合,如下所示:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
</InsertParameters>
</asp:ObjectDataSource>
重新執行精靈已新增回 OldValuesParameterFormatString
屬性。 請花點時間將此屬性設定為預設值, () {0}
或完全從宣告式語法中移除此屬性。
透過提供插入功能的 ObjectDataSource,DetailsView 的智慧標記現在會包含 [啟用插入] 複選框;返回 Designer,然後核取此選項。 接下來,剖析 DetailsView,使其只有兩個 BoundFields - ProductName
和 UnitPrice
- 和 CommandField。 此時,DetailsView 的宣告式語法看起來應該像這樣:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
圖 16 會在此時透過瀏覽器檢視時顯示此頁面。 如您所見,DetailsView 會列出第一個產品的名稱和價格, (Chai) 。 不過,我們想要的是插入介面,可提供使用者快速將新產品新增至資料庫的方法。
圖 16:D etailsView 目前以 Read-Only 模式轉譯, (按兩下即可檢視大小完整的影像)
為了在其插入模式中顯示 DetailsView,我們需要將 DefaultMode
屬性設定為 Inserting
。 這會在第一次瀏覽時呈現 Insert 模式中的 DetailsView,並在插入新記錄之後將它保留在該處。 如圖 17 所示,這類 DetailsView 提供快速介面來新增記錄。
圖 17:D etailsView 提供介面,讓您快速新增產品 (按兩下即可檢視大小完整的映像)
當使用者輸入產品名稱和價格 (,例如 「Acme Water」 和 1.99 時,如圖 17) ,然後按兩下 [插入],回傳會接續並開始插入工作流程,並進一步新增至資料庫的新產品記錄。 DetailsView 會維護其插入介面,GridView 會自動重新系結至其數據源,以包含新產品,如圖 18 所示。
圖 18:產品 「Acme Water」 已新增至資料庫
雖然圖 18 中的 GridView 未顯示它,但從 DetailsView 介面 CategoryID
、 SupplierID
、 QuantityPerUnit
等中缺少的產品欄位會指派 NULL
資料庫值。 您可以執行下列步驟來檢視此問題:
- 移至 Visual Studio 中的伺服器總管
- 展開
NORTHWND.MDF
資料庫節點 - 以滑鼠右鍵按兩下
Products
資料庫數據表節點 - 選取 [顯示資料表資料]
這會列出數據表中的所有 Products
記錄。 如圖 19 所示,除了 、 ProductName
和 以外的ProductID
所有新產品數據行都有NULL
UnitPrice
值。
圖 19:D etailsView 中未提供的產品欄位是 [指派 NULL
的值] (按鍵即可檢視大小完整的影像)
我們可能會想要提供一或多個數據行值以外的 NULL
預設值,可能是因為 NULL
不是最佳預設選項,或是資料庫數據行本身不允許 NULL
。 為了達成此目的,我們可以以程式設計方式設定 DetailsView 集合 InputParameters
的參數值。 您可以在 DetailsView ItemInserting
事件或 ObjectDataSource 事件的 Inserting
事件處理程式中完成此指派。 因為我們已經在數據 Web 控件層級使用前置和後置層級事件,讓我們這次使用 ObjectDataSource 的事件來探索。
步驟 4:將值指派給CategoryID
和SupplierID
參數
在本教學課程中,讓我們想像透過這個介面新增新產品時,應用程式應該指派 CategoryID
1 的 和 SupplierID
值。 如先前所述,ObjectDataSource 有一對在數據修改程序期間引發的前置和後置事件。 叫用其 Insert()
方法時,ObjectDataSource 會先引發其 Inserting
事件,然後呼叫其 Insert()
方法已對應的方法,最後會引發 Inserted
事件。 Inserting
事件處理程式提供最後一個機會來調整輸入參數,或直接取消作業。
注意
在真實世界中,您可能會想要讓使用者指定類別和供應商,或根據某些準則或商業規則來挑選此值 (,而不是盲目選取標識碼 1) 。 不論為何,此範例都會說明如何以程序設計方式從 ObjectDataSource 的預先層級事件設定輸入參數的值。
請花點時間建立 ObjectDataSource Inserting
事件的事件處理程式。 請注意,事件處理程式的第二個輸入參數是 類型的 ObjectDataSourceMethodEventArgs
物件,其具有屬性可存取參數集合 () InputParameters
,以及用來取消作業的屬性 Cancel
() 。
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
}
此時, InputParameters
屬性會包含 ObjectDataSource 的 InsertParameters
集合,其中包含從 DetailsView 指派的值。 若要變更下列其中一個參數的值,只需使用: e.InputParameters["paramName"] = value
。 因此,若要將 和 SupplierID
設定CategoryID
為1的值,請Inserting
調整事件處理程式,如下所示:
protected void ObjectDataSource1_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
e.InputParameters["CategoryID"] = 1;
e.InputParameters["SupplierID"] = 1;
}
這次新增新產品 (例如 Acme Soda) 時, CategoryID
新產品的 和 SupplierID
數據行會設定為 1 (請參閱圖 20) 。
圖 20:新產品現在將其 CategoryID
和 SupplierID
值設定為 1 (按鍵即可檢視完整大小的影像)
摘要
在編輯、插入和刪除程式期間,數據 Web 控制項和 ObjectDataSource 都會繼續執行一些前置和後置事件。 在本教學課程中,我們檢查了預先層級的事件,並瞭解如何使用這些事件來自定義輸入參數,或從數據 Web 控件和 ObjectDataSource 的事件完全取消數據修改作業。 在下一個教學課程中,我們將探討如何建立和使用後續層級事件的事件處理程式。
快樂的程序設計!
關於作者
Scott Mitchell 是 1998 年以來,1998 年與 Microsoft Web 技術合作的 七篇 ASP/ASP.NET 書籍和 4GuysFromRolla.com 作者。 Scott 是獨立的顧問、訓練者和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格連到,也可以透過其部落格來存取,網址為 http://ScottOnWriting.NET。
特別感謝
本教學課程系列是由許多實用的檢閱者所檢閱。 本教學課程的首席檢閱者是 Jackie Goor 和 Liz Shulok。 想要檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應