科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Visual Basic.NET进行事件编程

Visual Basic.NET进行事件编程

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文的目标就是让你了解事件在低层是怎样工作的

作者:陶刚编译 来源:yesky 2007年11月9日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
建立和注册事件处理程序

  现在你已经知道怎样定义和引发事件了,下面讲解怎样建立事件处理程序并使用给定的源对它进行注册。在Visual Basic .NET中有两种途径可以达到这个目标。第一种技术是我们知道的动态事件绑定并且包含AddHandler关键字的使用。第二种技术是静态事件绑定并且包含与Visual Basic相似的WithEvents关键字。本文中我将使用动态事件绑定,下面将讲解动态事件绑定是怎样工作的。

  要记住事件处理程序是委托对象。因此你通过作为事件基础的委托类型实例化委托对象来建立事件处理程序。当你建立委托对象时,你必须把它绑定到作为事件处理程序服务的目标处理方法。

  一旦建立了事件处理程序,你就必须通过调用事件源上特定的注册方法用特定的事件注册它。回想一下,LargeWithdraw事件的注册方法叫做add_LargeWithdraw。当你调用add_LargeWithdraw方法并传递一个委托对象作为参数时,事件源把委托对象添加到接收事件通知的事件处理程序列表中。

  事件注册容易弄混的是你永远不能直接的调用类似add_LargeWithdraw的注册方法。事实上,如果你试图用名字访问事件注册方法,Visual Basic .NET编译器将产生一个实时编译错误。作为代替,你能使用包含在AddHandler语句中的代替语法。当你使用AddHandler语句时,Visual Basic .NET编译器为你产生调用事件注册方法的代码。

  让我们看一个使用动态事件注册的例子。假定你在AccountHandlers类中写了下面一组共享方法:

Class AccountHandlers
Shared Sub LogWithdraw(ByVal Amount As Decimal)
'把撤消信息写入日志文件
End Sub

Shared Sub GetApproval(ByVal Amount As Decimal)
'阻塞直到管理者批准
End Sub
End Class

  如果你想把这些方法作为BankAccount类中的LargeWithdraw事件的事件处理程序应该怎么做呢?我们从建立一个绑定到LargeWithdraw的事件处理程序开始。首先你必须建立作为事件处理程序服务的委托对象:

Dim handler1 As LargeWithdrawHandler
handler1 = AddressOf AccountHandlers.LogWithdraw

  下一步,你必须使用AddHandler语句与事件源一起注册该委托对象。当你使用AddHandler语句注册事件处理程序时,必须传递两个参数:

AddHandler <event>, <delegate object>

  AddHandler所需要的第一个参数是计算类或对象的事件的表达式,第二个参数是一个联系事件处理程序的委托对象的引用。下面是使用AddHandler语句与BankAccount对象的LargeWithdraw事件一起注册事件处理程序的例子:

'建立银行帐号对象
Dim account1 As New BankAccount()

'建立并注册一个事件处理程序
Dim handler1 As LargeWithdrawHandler
handler1 = AddressOf AccountHandlers.LogWithdraw
AddHandler account1.LargeWithdraw, handler1

  当你为LargeWithdraw事件使用AddHandler注册一个事件处理程序时,Visual Basic .NET编译器扩展这些代码来调用注册方法add_LargeWithdraw。一旦包含AddHandler语句的代码执行了,事件处理程序便就位了并且为通知做好了准备。因此无论什么时候BankAccount对象引发一个LargeWithdraw事件,LargeWithdraw方法都将执行。

  在最后一个例子中,我使用长语法来说明当你建立和注册一个事件处理程序时到底发生了什么事情。但是,一旦你明白事情是怎样的,你也许会感激使用了更简洁的语法实现了相同的目标:

'建立银行帐号对象
Dim account1 As New BankAccount()

'注册事件处理程序
AddHandler account1.LargeWithdraw, AddressOf AccountHandlers.LogWithdraw
AddHandler account1.LargeWithdraw, AddressOf AccountHandlers.GetApproval

  因为AddHandler语句期待一个委托对象作为第二个参数,你能使用速记语法--AddressOf操作符后紧跟目标处理方法的名字。当Visual Basic .NET编译器看到该语法时,它接着产生额外的代码来建立作为事件处理程序服务的委托对象。

  Visual Basic .NET 语言中的AddHandler语句的补充是RemoveHandler语句。RemoveHandler需要的参数与AddHandler的相同,它的效果相反。它通过事件源调用remove_LargeWithdraw方法从已注册的处理方法列表中删除目标处理方法。

Dim account1 As New BankAccount()

'注册事件处理程序
AddHandler account1.LargeWithdraw, AddressOf AccountHandlers.LogWithdraw

'删除事件处理程序注册
RemoveHandler account1.LargeWithdraw, AddressOf AccountHandlers.LogWithdraw

  你已经看到了实现使用事件的回调设计需要的所有步骤了。图4中的代码显示了一个完整的应用程序,在该程序中已经注册了两个事件处理程序从BankAccount对象的LargeWithdraw事件接收回调通知。

Delegate Sub LargeWithdrawHandler(ByVal Amount As Decimal)

Class BankAccount
Public Event LargeWithdraw As LargeWithdrawHandler
Sub Withdraw(ByVal Amount As Decimal)
'如果需要的话就发送通知
If (Amount > 5000) Then
RaiseEvent LargeWithdraw(Amount)
End If
'执行撤消
End Sub
End Class

Class AccountHandlers
Shared Sub LogWithdraw(ByVal Amount As Decimal)
'把撤消信息写入日志文件
End Sub
Shared Sub GetApproval(ByVal Amount As Decimal)
'阻塞直到管理者批准
End Sub
End Class

Module MyApp
Sub Main()
'建立银行帐号对象
Dim account1 As New BankAccount()
'注册事件处理程序
AddHandler account1.LargeWithdraw, _
AddressOf AccountHandlers.LogWithdraw
AddHandler account1.LargeWithdraw, _
AddressOf AccountHandlers.GetApproval
'做一些触发回调的事情
account1.Withdraw(5001)
End Sub
End Module


图4.用于回调通知的基于事件的设计

  结论

  尽管使用事件的动机和一些语法与早期版本的Visual Basic相比仍然没有改变,但是你不得不承认情况有很大不同了。你能看到,你对如何响应事件的控制力比以前大多了。如果你将使用委托编程,这就很实际了。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章