处理数据控件事件
您已经在本教程的前面几节中看到了数据控件事件的几个示例。数据控件事件旨在为您提供在页面执行生命周期中可插入自己的自定义代码的适当位置。数据控件一般在特定操作发生之前和之后公开事件。在操作之前激发的事件通常使用 -ing 后缀进行命名,而在操作之后激发的事件则使用 -ed 后缀进行命名。例如,GridView 支持的事件包括:
PageIndexChanging 和 PageIndexChanged -- 在分页操作之前和之后引发
SelectedIndexChanging 和 SelectedIndexChanged -- 在选择操作之前和之后引发
Sorting 和 Sorted -- 在排序操作之前和之后引发
RowEditing 和 RowCancelingEdit -- 在行进入编辑模式之前或在编辑模式被取消之前引发
RowUpdating 和 RowUpdated -- 在更新操作之前和之后引发
RowDeleting 和 RowDeleted -- 在删除操作之前和之后引发
RowDataBound -- 当行与数据绑定时引发
RowCreated -- 当创建行用于呈现(作为 TableRow)时引发
RowCommand -- 当从控件中激发按钮命令时引发
数据源控件也公开事件,类似于数据绑定控件事件。SqlDataSource 和 ObjectDataSource 控件都支持下列事件:
Selecting 和 Selected -- 在选择操作之前和之后引发
Updating 和 Updated -- 在更新操作之前和之后引发
Deleting 和 Deleted -- 在删除操作之前和之后引发
Inserting 和 Inserted -- 在插入操作之前和之后引发
Filtering -- 在筛选器操作之前引发
ObjectDataSource 控件还在 TypeName 属性所指定的对象被创建或销毁时额外公开一些事件。通过设置所传递的事件参数的 ObjectInstance 属性,可以在 ObjectCreating 事件中实际设置一个自定义对象。
ObjectCreating 和 ObjectCreated -- 在对象被创建之前和之后引发
ObjectDisposing -- 在对象被释放之前引发
通常,在操作发生之前激发的事件用于取消操作(通过将事件参数的 Cancel 属性设置为 true),或用于执行参数验证或处理。在操作之后引发的事件用于编写自定义代码以响应给定的操作,或用于检查操作的成功状态。例如,可以检查 Update、Insert 或 Delete 操作导致的 RowsAffected,或检查 Exception 属性以确定处理期间是否发生了异常。还可以设置事件参数的 ExceptionHandled 属性以防止异常向上冒泡到控件或页。下面的示例演示可处理的各种 GridView 和 SqlDataSource 事件和它们被引发的相对顺序。
C# GridView RowUpdating Event
下一个示例演示 DetailsView Inserting 事件的更实用的处理,其中处理代码从 DetailsView 中的 FileUpload 控件获得张贴的照片文件,以便在 DetailsView 完成在数据库中为所张贴的文件插入一条记录的操作之前,将内容保存到磁盘。出于演示的目的,实际的文件保存代码已被注释掉,不过您仍然可以通过指定已经存在的“Winter.jpg”图像的名称试验一下此示例。
C# DetailsView ItemInserting Event
与上面的示例类似,此示例演示 FormView ItemDeleted 事件的处理,以便在删除该照片的数据库记录时从磁盘删除关联的照片文件。同样出于演示的目的,实际的文件删除代码已被注释掉。
C# FormView ItemDeleted Event
使用参数
可以处理 Select、Update、Insert、Delete 和 Filter 操作的事件以验证和处理传递给这些操作的参数值。数据绑定控件和数据源控件都公开用于此目的的适当事件。例如,在 GridView Updating 事件中,您可以查看 Keys、NewValues 和 OldValues 字典中将传递给数据源的参数的名称和值。在数据源一端,您可以处理 SqlDataSource Updating 事件,以便在这些参数被应用于将执行以完成操作的基础命令对象时查看这些参数。类似地,可以处理 ObjectDataSource Updating 事件以查看或更改将用于解析 UpdateMethod 方法的适当重载的参数字典。可以使用这些事件添加或移除字典或命令中的参数,更改它们的值,或者只是验证参数是否具有正确的输入格式。
重要说明:尤其应该验证 Filtering 事件的参数输入,这些参数在应用于与 DataView 对象关联的 FilterExpression 之前,未经过 SQL 编码。
下面的示例演示如何处理各种数据控件事件以枚举通过事件参数传递的参数集合。注意,此示例将与 OrderID 主键字段关联的 BoundField 的 InsertVisible 属性设置为 false,因为 OrderID 字段是基础数据库中的标识列,不应该将它传递给 Insert 操作(数据库在插入操作发生时自动递增此值)。另请注意,OrderID 字段被标记为 DataKeyNames 中的主键,所以此字段的原始值保留在数据绑定控件所传递的 Keys 字典中。用户向输入控件中输入的值在 NewValues 字典中传递,不过标记为 ReadOnly=false 的字段除外。非键字段的原始值也由数据绑定控件保留在一个 OldValues 字典中,以用于传递给数据源。这些参数值由 SqlDataSource 按照 NewValues、Keys 和 OldValues 的顺序追加到命令上,不过在 ConflictDetection 设置为 OverwriteChanges 时,数据源默认不追加 OldValues。有关数据源如何使用 OldValues 的更多信息,请参考下面的“使用冲突检测”一节。
C# Data Parameters
通过按照自己喜欢的顺序将静态 Parameter 对象添加到数据源操作的参数集合,可以更改 SqlDataSource 向命令追加参数的顺序。SqlDataSource 自动根据这些 Parameter 对象的顺序对数据绑定控件传递的参数重新排序。这在数据源的 ProviderName 属性设置为 System.Data.OleDb 时很有用,因为此设置不支持命名的参数,所以向命令追加参数的顺序必须与命令中的匿名参数占位符(“?”)的顺序相匹配。当使用命名的参数时,参数的顺序无关紧要。可以指定 Parameter 对象的 Type 属性,以便在执行命令或方法之前,强制将数据绑定控件传递的值转换为适当的数据类型。同样,可以设置 Parameter 的 Size 属性,以指示 SqlDataSource 命令中的 DbParameter 的 Size (这是输入/输出、输出和返回值参数所需要的)。
C# Param eter Order and Types
参数名称的默认约定要求按照数据源 Select 操作所选择的字段对新值进行命名。通过指定 OldValuesParameterFormatString 属性(例如“original_{0}”),可以对来自 Keys 或 OldValues 的参数重命名,以将它们与 NewValues 区别开来。通过处理相应的事件以便在执行数据源操作之前更改参数的值,您还可以自定义参数的名称。例如,如果 SqlDataSource 的更新操作与某个存储过程关联,该存储过程采用的参数名称与匹配默认约定的名称不同,您可以在调用该存储过程之前在 SqlDataSource Updating 事件中修改参数名称。下面的示例演示了此项技术。
C# Renaming Parameters