事件处理程序的协同工作原理
除非使用 Visual Basic 进行编程,否则必须实现 Connection 和 Recordset 事件的所有事件处理程序,无论是否真的会处理所有事件。 必须完成的实现工作量取决于你的编程语言。 有关详细信息,请参阅 ADO 事件实例化(按语言)。
配对事件处理程序
每个 Will 事件处理程序都有关联的 Complete 事件处理程序。 例如,当应用程序更改字段的值时,将调用 WillChangeField 事件处理程序。 如果更改是可接受的,则应用程序将保留 adStatus 参数不变并执行该操作。 操作完成后,FieldChangeComplete 事件会通知你的应用程序操作已完成。 如果成功完成,adStatus 将包含 adStatusOK;否则,adStatus 将包含 adStatusErrorsOccurred,必须检查 Error 对象以确定错误原因。
调用 WillChangeField 时,你可能会确定不应进行更改。 在这种情况下,请将 adStatus 设置为 adStatusCancel。该操作被取消,FieldChangeComplete 事件收到 adStatus 值 adStatusErrorsOccurred。 Error 对象包含 adErrOperationCancelled,以便 FieldChangeComplete 处理程序知道操作已取消。 但是,在更改 adStatus 参数之前,需要检查其值,因为如果在进入过程时将参数设置为 adStatusCantDeny,则将 adStatus 设置为 adStatusCancel 将不起作用。
有时,一个操作可能会引发多个事件。 例如,Recordset 对象具有字段更改和记录更改的配对事件。 当应用程序更改字段的值时,将调用 WillChangeField 事件处理程序。 如果确定该操作可以继续,也会引发 WillChangeRecord 事件处理程序。 如果此处理程序也允许事件继续,则会进行更改并调用 FieldChangeComplete 和 RecordChangeComplete 事件处理程序。 未定义特定操作的 Will 事件处理程序的调用顺序,因此应避免编写依赖于以特定顺序调用处理程序的代码。
在引发多个 Will 事件的情况下,其中一个事件可能会取消挂起的操作。 例如,当应用程序更改 Field 的值时,通常会调用 WillChangeField 和 WillChangeRecord 事件处理程序。 但是,如果在第一个事件处理程序中取消了该操作,则会立即使用 adStatusOperationCancelled 调用其关联的 Complete 处理程序。 从不调用第二个处理程序。 但是,如果第一个事件处理程序允许事件继续,则将调用另一个事件处理程序。 如果它随后取消操作,将会调用两个 Complete 事件,如前面的示例中所示。
未配对事件处理程序
只要传递给事件的状态不是 adStatusCantDeny,便可以通过在 Status 参数中返回 adStatusUnwantedEvent 来关闭任何事件的事件通知。 例如,第一次调用 Complete 事件处理程序时,可以返回 adStatusUnwantedEvent。 随后将仅收到 Will 事件。 但是,某些事件可能会因多种原因而触发。 在这种情况下,事件将有一个 Reason 参数。 如果返回 adStatusUnwantedEvent,则仅当事件因特定原因发生时,你才会停止接收该事件的通知。 换句话说,你可能会收到有关可能触发事件的每个可能原因的通知。
如果要检查将在操作中使用的参数,单个 Will 事件处理程序会很有用。 可以修改这些操作参数或取消操作。
或者,使 Complete 事件通知保持启用状态。 调用第一个 Will 事件处理程序时,返回 adStatusUnwantedEvent。 随后将仅收到 Complete 事件。
单个 Complete 事件处理程序可用于管理异步操作。 每个异步操作都有一个相应的 Complete 事件。
例如,填充大型 Recordset 对象可能需要很长时间。 如果应用程序编写得当,则可以启动 Recordset.Open(...,adAsyncExecute)
操作并继续进行其他处理。 当 Recordset 由 ExecuteComplete 事件填充时,你最终会收到通知。
单个事件处理程序和多个对象
Visual C++ 等编程语言的灵活性使得能够使用一个事件处理程序处理来自多个对象的事件。 例如,你可以让一个 Disconnect 事件处理程序处理来自多个 Connection 对象的事件。 如果其中一个连接结束,将调用 Disconnect 事件处理程序。 可以判断出是哪个连接导致了该事件,因为事件处理程序对象参数将设置为相应的 Connection 对象。
注意
Visual Basic 中无法使用此方法,因为该语言只能将一个对象关联到一个事件处理程序。