检查与插入、更新和删除操作有关的事件 (VB)
作者 :斯科特·米切尔
在本教程中,我们将使用 ASP.NET 数据 Web 控件的插入、更新或删除操作之前、期间和之后发生的事件。 我们还将了解如何自定义编辑界面以仅更新产品字段的子集。
介绍
使用 GridView、DetailsView 或 FormView 控件的内置插入、编辑或删除功能时,最终用户完成添加新记录或更新或删除现有记录的过程时,会执行各种步骤。 如上一教程中所述,在 GridView 中编辑行时,“编辑”按钮将替换为“更新”和“取消”按钮,而 BoundFields 将转换为 TextBoxes。 最终用户更新数据并单击“更新”后,在回发时执行以下步骤:
- GridView 使用编辑的记录的唯一标识字段(s)以及
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 将传入业务逻辑层 (BLL) 方法的值Nothing
UpdateProduct
,该方法会将编辑的数据库记录的QuantityPerUnit
列更改为值NULL
。 同样,如果从编辑界面中删除所需的字段(例如 ProductName
),更新将失败,并显示“列'ProductName'不允许 nulls”异常。 此行为的原因是 ObjectDataSource 配置为调用 ProductsBLL
类 UpdateProduct
的方法,该方法需要每个产品字段的输入参数。 因此,ObjectDataSource 的 UpdateParameters
集合包含每个方法输入参数的参数。
如果我们想要提供一个数据 Web 控件,该控件允许最终用户仅更新字段的子集,则需要以编程方式在 ObjectDataSource 的Updating
事件处理程序中设置缺失UpdateParameters
值,或者创建并调用只需要字段子集的 BLL 方法。 让我们探讨一下后一种方法。
具体而言,让我们创建一个页面,仅显示 ProductName
可编辑 GridView 中的字段和 UnitPrice
字段。 此 GridView 的编辑界面仅允许用户更新两个显示的字段, ProductName
以及 UnitPrice
。 由于此编辑接口仅提供产品的字段子集,因此我们要么需要创建使用现有 BLL 方法的 UpdateProduct
ObjectDataSource,并在其 Updating
事件处理程序中以编程方式设置缺少的产品字段值,或者我们需要创建一个新的 BLL 方法,该方法只期望 GridView 中定义的字段子集。 在本教程中,让我们使用后一个选项并创建方法的 UpdateProduct
重载,该方法只采用三个输入参数: productName
、 unitPrice
和 productID
:
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Update, False)> _
Public Function UpdateProduct(productName As String, _
unitPrice As Nullable(Of Decimal), productID As Integer) _
As Boolean
Dim products As Northwind.ProductsDataTable = _
Adapter.GetProductByProductID(productID)
If products.Count = 0 Then
Return False
End If
Dim product As Northwind.ProductsRow = products(0)
product.ProductName = productName
If Not unitPrice.HasValue Then
product.SetUnitPriceNull()
Else
product.UnitPrice = unitPrice.Value
End If
Dim rowsAffected As Integer = Adapter.Update(product)
Return rowsAffected = 1
End Function
与原始 UpdateProduct
方法一样,此重载首先检查数据库中是否存在具有指定 ProductID
值的产品。 如果没有,它将返回 False
,指示更新产品信息的请求失败。 否则,它会相应地更新现有产品记录和ProductName
UnitPrice
字段,并通过调用 TableAdapter Update()
的方法(ProductsRow
传入实例)提交更新。
除了类 ProductsBLL
之外,我们已准备好创建简化的 GridView 接口。 打开DataModificationEvents.aspx
EditInsertDelete
文件夹中,将 GridView 添加到页面。 创建新的 ObjectDataSource 并将其配置为将ProductsBLL
类与方法Select()
映射GetProducts
一起使用,并将其Update()
方法映射到UpdateProduct
仅采用和unitPrice
productID
输入参数的productName
重载。 图 2 显示了将 ObjectDataSource Update()
方法映射到 ProductsBLL
类的新 UpdateProduct
方法重载时的“创建数据源”向导。
图 2:将 ObjectDataSource Update()
的方法映射到新 UpdateProduct
重载(单击可查看全尺寸图像)
由于我们的示例最初只需要能够编辑数据,但不能插入或删除记录,因此请花点时间显式指示 ObjectDataSource 和Insert()
Delete()
方法不应通过转到 INSERT 和 DELETE 选项卡并从下拉列表中选择(None)来映射到类的任何ProductsBLL
方法。
图 3:从“插入”和“删除”选项卡的下拉列表中选择(无)(单击以查看全尺寸图像)
完成此向导后,选中 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()
方法没有映射,因此没有或DeleteParameters
部分InsertParameters
。 此外,由于该方法 Update()
映射到 UpdateProduct
仅接受三个输入参数的方法重载,因此该 UpdateParameters
节只有三 Parameter
个实例。
请注意,ObjectDataSource 的属性 OldValuesParameterFormatString
设置为 original_{0}
. 使用“配置数据源”向导时,Visual Studio 会自动设置此属性。 但是,由于 BLL 方法不希望传入原始 ProductID
值,因此请完全从 ObjectDataSource 的声明性语法中删除此属性分配。
注意
如果只是从设计视图中的属性窗口中清除OldValuesParameterFormatString
属性值,该属性仍将存在于声明性语法中,但将设置为空字符串。 从声明性语法中删除该属性,或者从属性窗口中将值设置为默认值{0}
。
虽然 ObjectDataSource 仅具有 UpdateParameters
产品的名称、价格和 ID,但 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
仅采用产品名称、价格和 ID 的重载,我们需要将 GridView 限制为仅ProductName
UnitPrice
具有可编辑字段。 这可以通过删除其他 BoundFields 和 CheckBoxFields、将其他字段 ReadOnly
的属性 True
设置为或两者的某些组合来实现。 在本教程中,我们只需删除除 BoundFields 以外的ProductName
UnitPrice
所有 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 中只有两个 BoundFields。 这是因为 productID
输入参数是主键值,通过编辑行的属性值 DataKeyNames
传入。
我们的 GridView 以及 UpdateProduct
重载允许用户仅编辑产品的名称和价格,而不会丢失任何其他产品字段。
图 6:界面仅允许编辑产品名称和价格(单击可查看全尺寸图像)
注意
如上一教程中所述,启用 GridView 的视图状态(默认行为)至关重要。 如果将 GridView 属性 EnableViewState
设置为 false
,则可能会无意中删除或编辑记录并发用户。
UnitPrice
改进格式设置
虽然图 6 中显示的 GridView 示例有效,但 UnitPrice
该字段根本不是格式化的,因此价格显示缺少任何货币符号,并且具有四个小数位数。 若要为不可编辑的行应用货币格式设置,只需将 UnitPrice
BoundField 的属性DataFormatString
设置为{0:c}
其HtmlEncode
属性。False
图 7:相应地设置UnitPrice
“和HtmlEncode
DataFormatString
”属性“(单击可查看全尺寸图像)
通过此更改,不可编辑的行将价格格式化为货币;但是,编辑的行仍然显示没有货币符号的值,并带有四个小数位数。
图 8:不可编辑的行现在已格式化为货币值(单击以查看全尺寸图像)
通过将 BoundField ApplyFormatInEditMode
的属性设置为 True
(默认值为 False
),可以将属性中指定的DataFormatString
格式设置说明应用于编辑接口。 花点时间将此属性设置为 True
.
图 9:将 UnitPrice
BoundField ApplyFormatInEditMode
的属性设置为 True
(单击可查看全尺寸图像)
通过此更改,编辑后的行中显示的值 UnitPrice
也格式化为货币。
图 10:编辑后的 UnitPrice
行值现在已格式化为货币(单击以查看全尺寸图像)
但是,使用 19.00 美元等文本框中的货币符号更新产品会引发一个 FormatException
。 当 GridView 尝试将用户提供的值分配给 ObjectDataSource 的 UpdateParameters
集合时,无法将 UnitPrice
字符串“$19.00”转换为 Decimal
参数所需的值(请参阅图 11)。 为了解决此问题,我们可以为 GridView RowUpdating
的事件创建事件处理程序,并将其分析为货币格式Decimal
的用户UnitPrice
。
GridView RowUpdating
的事件接受其第二个参数 GridViewUpdateEventArgs 类型的对象,该对象包含字典NewValues
作为其属性之一,用于保存可供分配给 ObjectDataSource 集合UpdateParameters
的用户提供的值。 可以使用使用货币格式在事件处理程序中的NewValues
以下代码行中用货币格式分析的小数值覆盖集合中的RowUpdating
现有UnitPrice
值:
Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
Handles GridView1.RowUpdating
If e.NewValues("UnitPrice") IsNot Nothing Then
e.NewValues("UnitPrice") = _
Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
System.Globalization.NumberStyles.Currency)
End If
End Sub
如果用户已提供UnitPrice
值(如“$19.00”),则使用 Decimal.Parse 计算的十进制值覆盖此值,将该值分析为货币。 如果出现任何货币符号、逗号、小数点等,则会正确分析小数,并在 System.Globalization 命名空间中使用 NumberStyles 枚举。
图 11 显示了用户提供的 UnitPrice
货币符号导致的这两个问题,以及如何使用 GridView 的 RowUpdating
事件处理程序来正确分析此类输入。
图 11:编辑后的 UnitPrice
行值现在已格式化为货币(单击以查看全尺寸图像)
步骤 2:禁止NULL UnitPrices
虽然数据库配置为允许NULL
表列中的值Products
,但我们可能希望阻止访问此特定页面的用户指定NULL
UnitPrice
UnitPrice
值。 也就是说,如果用户在编辑产品行时无法输入 UnitPrice
值,而不是将结果保存到要显示的消息,告知用户,通过此页面,任何编辑的产品都必须指定价格。
GridViewUpdateEventArgs
传递到 GridView 事件处理程序的对象RowUpdating
包含一个Cancel
属性,如果设置为True
该属性,则终止更新过程。 让我们扩展RowUpdating
事件处理程序以设置为e.Cancel
True
并显示一条消息,说明集合中的NewValues
值是否UnitPrice
具有值Nothing
的原因。
首先将标签 Web 控件添加到名为 MustProvideUnitPriceMessage
的页面。 如果用户在更新产品时无法指定 UnitPrice
值,将显示此标签控件。 将标签Text
的属性设置为“必须提供产品的价格”。我还使用以下定义创建了一个新的 CSS 类Styles.css
Warning
:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
最后,将 Label CssClass
的属性设置为 Warning
。 此时,设计器应以红色、粗体、斜体、超大型字体大小显示警告消息,如图 12 所示。
图 12:在 GridView 上方添加了标签(单击以查看全尺寸图像)
默认情况下,此标签应隐藏,因此将其 Visible
属性设置为 False
在事件处理程序中 Page_Load
:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
MustProvideUnitPriceMessage.Visible = False
End Sub
如果用户尝试在不指定 UnitPrice
产品的情况下更新产品,我们希望取消更新并显示警告标签。 按如下所示扩充 GridView 的 RowUpdating
事件处理程序:
Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
Handles GridView1.RowUpdating
If e.NewValues("UnitPrice") IsNot Nothing Then
e.NewValues("UnitPrice") = _
Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
System.Globalization.NumberStyles.Currency)
Else
MustProvideUnitPriceMessage.Visible = True
e.Cancel = True
End If
End Sub
如果用户尝试在不指定价格的情况下保存产品,则会取消更新并显示一条有用的消息。 虽然数据库(和业务逻辑)允许NULL
UnitPrice
这样做,但此特定 ASP.NET 页则不允许。
图 13:用户无法留 UnitPrice
空(单击以查看全尺寸图像)
到目前为止,我们已了解如何使用 GridView 的事件 RowUpdating
以编程方式更改分配给 ObjectDataSource UpdateParameters
集合的参数值,以及如何完全取消更新过程。 这些概念延续到 DetailsView 和 FormView 控件,还适用于插入和删除。
还可以通过事件处理程序在 ObjectDataSource 级别完成这些任务,以及Deleting
事件Inserting
Updating
。 这些事件在调用基础对象的关联方法之前触发,并提供修改输入参数集合或彻底取消操作的最后机会。 这三个事件的事件处理程序将传递一个 ObjectDataSourceMethodEventArgs 类型的对象,该对象具有两个感兴趣的属性:
- 取消,如果设置为
True
“取消”,则取消正在执行的操作 - InputParameters,它是
UpdateParameters/a0> 的 InsertParameters
集合,或者DeleteParameters
,具体取决于事件处理程序是针对Inserting
Updating
Deleting
或事件
为了说明如何在 ObjectDataSource 级别使用参数值,让我们在页面中包括一个 DetailsView,允许用户添加新产品。 此 DetailsView 将用于提供一个接口,用于将新产品快速添加到数据库。 若要在添加新产品时保持一致的用户界面,让我们允许用户仅输入字段的值ProductName
UnitPrice
。 默认情况下,DetailsView 插入接口中未提供的这些值将设置为 NULL
数据库值。 但是,可以使用 ObjectDataSource Inserting
的事件来注入不同的默认值,正如我们不久将看到的那样。
步骤 3:提供用于添加新产品的接口
将 DetailsView 从工具箱拖到 GridView 上方的设计器上,清除其 Height
属性 Width
,并将其绑定到页面上已存在的 ObjectDataSource。 这将为每个产品的字段添加 BoundField 或 CheckBoxField。 由于我们希望使用此 DetailsView 添加新产品,因此我们需要从智能标记中检查“启用插入”选项;但是,没有这样的选项,因为 ObjectDataSource Insert()
的方法未映射到类中的 ProductsBLL
方法(回想一下,在配置数据源时,我们将此映射设置为“无”),请参阅图 3。
若要配置 ObjectDataSource,请从其智能标记中选择“配置数据源”链接,启动向导。 第一个屏幕允许更改 ObjectDataSource 绑定到的基础对象;将其设置为 ProductsBLL
. 下一个屏幕列出了从 ObjectDataSource 方法到基础对象的映射。 尽管我们明确指示 Insert()
不应将和 Delete()
方法映射到任何方法,但如果转到 INSERT 和 DELETE 选项卡,则会看到映射存在。 这是因为ProductsBLL
's AddProduct
和DeleteProduct
方法使用DataObjectMethodAttribute
特性来指示它们是默认方法,并且Delete()
分别是默认方法Insert()
。 因此,每次运行向导时,ObjectDataSource 向导都会选择这些值,除非显式指定了一些其他值。
Insert()
使方法指向AddProduct
该方法,但再次将 DELETE 选项卡的下拉列表设置为 (None)。
图 14:将 INSERT 选项卡的下拉列表设置为 AddProduct
方法(单击可查看全尺寸图像)
图 15:将 DELETE 选项卡的下拉列表设置为“无”(单击以查看全尺寸图像)
进行这些更改后,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 的智能标记现在将包括“启用插入”复选框;返回设计器并选中此选项。 接下来,分析 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:DetailsView 当前以只读模式呈现(单击以查看全尺寸图像)
为了在其插入模式下显示 DetailsView,我们需要将 DefaultMode
属性设置为 Inserting
。 当首次访问详细信息视图并在插入新记录后保留该视图时,这将呈现为插入模式。 如图 17 所示,此类 DetailsView 提供了用于添加新记录的快速界面。
图 17:DetailsView 提供用于快速添加新产品的界面(单击以查看全尺寸图像)
当用户输入产品名称和价格(如“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 所示,除其他所有新产品列外ProductID
ProductName
,还UnitPrice
具有NULL
值。
图 19:DetailsView 中未提供的产品字段已 NULL
分配值(单击以查看全尺寸图像)
我们可能想要为一个或多个这些列值提供默认值 NULL
,要么 NULL
不是最佳默认选项,要么是因为数据库列本身不允许 NULL
。 为此,我们可以以编程方式设置 DetailsView InputParameters
集合的参数值。 可以在 DetailsView 事件或 ItemInserting
ObjectDataSource Inserting
的事件的事件处理程序中完成此分配。 由于我们已在数据 Web 控件级别使用前和后级别事件,因此让我们这次使用 ObjectDataSource 的事件进行探索。
步骤 4:向参数SupplierID
分配值CategoryID
在本教程中,我们假设在通过此接口添加新产品时,应用程序应分配一个 CategoryID
值和 SupplierID
值 1。 如前所述,ObjectDataSource 具有一对在数据修改过程中触发的前后级别事件。 调用其 Insert()
方法时,ObjectDataSource 首先引发其 Inserting
事件,然后调用其 Insert()
方法已映射到的方法,最后引发该 Inserted
事件。 Inserting
事件处理程序提供了我们最后一个调整输入参数或彻底取消操作的机会。
注意
在实际应用程序中,你可能希望让用户指定类别和供应商,或者根据某些条件或业务逻辑(而不是盲目选择 ID 为 1)为它们选取此值。 不管怎样,该示例都演示如何从 ObjectDataSource 的预级别事件以编程方式设置输入参数的值。
花点时间为 ObjectDataSource Inserting
的事件创建事件处理程序。 请注意,事件处理程序的第二个输入参数是一个类型 ObjectDataSourceMethodEventArgs
的对象,该对象具有访问参数集合(InputParameters
)的属性和用于取消操作的属性(Cancel
)。
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
End Sub
此时,该 InputParameters
属性包含 ObjectDataSource 的集合, InsertParameters
其中包含从 DetailsView 分配的值。 若要更改其中一个参数的值,只需使用: e.InputParameters("paramName") = value
因此,若要设置 CategoryID
和 SupplierID
设置为 1 的值,请 Inserting
调整事件处理程序,如下所示:
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
e.InputParameters("CategoryID") = 1
e.InputParameters("SupplierID") = 1
End Sub
这一次,添加新产品(如 Acme Soda), CategoryID
新产品的列 SupplierID
设置为 1(请参阅图 20)。
图 20:新产品现在已将其 CategoryID
值 SupplierID
设置为 1(单击可查看全尺寸图像)
总结
在编辑、插入和删除过程中,数据 Web 控件和 ObjectDataSource 都继续执行许多预先和后级别事件。 在本教程中,我们检查了预级事件,并了解了如何使用这些事件来自定义输入参数或完全取消数据修改操作,以及数据 Web 控件和 ObjectDataSource 的事件。 在下一教程中,我们将介绍如何为后期事件创建和使用事件处理程序。
快乐编程!
关于作者
斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0。 他可以通过他的博客联系到mitchell@4GuysFromRolla.com他,可以在该博客中找到http://ScottOnWriting.NET。
特别感谢
本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是 Jackie Goor 和 Liz Shulok。 有兴趣查看即将发布的 MSDN 文章? 如果是这样,请把我扔一条线。mitchell@4GuysFromRolla.com