首页 > OOP语言 > VB.net > 正文

vb.net之旅(十四)―动态关联事件与处理程序
2012-09-03 00:00:00   来源:www.bianceng.cn   评论:0 点击:

暂时无描述信息

“要解释新的事件处理程序的方法,我们需要先说几个重要的问题。 ”大李开始严肃起来,我也只得挪动一下身子,表现出正襟危坐的架势。

“我们首先讨论一下事件是怎么产生的。事件是对象发送的消息, 以发信号通知操作的发生。操作可能是由用户交互,例如鼠标单击引起的,也可 能是由某些其他的程序逻辑触发的。引发事件的对象叫做事件发送方(啊,听到 这,henry突然明白了事件处理程序中的第一个参量为什么叫sender了,就是指事 件发送的那个对象呀)。捕获事件并对其作出响应的对象叫做事件接收方。在事 件通讯中,事件发送方类不知道哪个对象或方法将接收到它引发的事件。所需要 的是在源和接收方之间存在一个媒介,或类似指针的机制。.net 框架定义了一个 特殊的类型delegate,也就是委托,该类型提供函数指针的功能。 ”

“啊,我早就听说过委托的,就是不知道它是什么意思咧! ”我做出期盼状。

“委托就是可用于调用其他对象方法的对象 。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进 行引用。”大李继续说着。

““噢,委托也就是一个函 数指针喽。”我好象理解了一点。

“差不多,委托可以等效于 一个类型安全函数指针或一个回调。但不同于函数指针,visual basic.net 委托 是基于 system.delegate 类的引用类型,它可以引用我们先前说过的共享方法( 详见《共享成员》一篇)和实例方法。”

“明白了一点。 ”我一边点头一边说,“我们想要动态调用事件处理程序,是不是就 要利用委托来声明是哪个程序用于处理事件呀?”

大李惊异地看着 我,露出了几分赞许。

“委托是.net中的一个重要的类型,我们以 后还需要详细讨论。现在我们需要关注的就是如何来通过操作委托来实现将事件 与事件处理程序动态联系起来。”大李接着就开始修改代码:

module module1
public class chenry
        public event eventhr()    ´ 声明一个事件
        sub causesomeevent()
            raiseevent eventhr()   ´ 引发事件
        end sub
    end class
 
    dim obj as new chenry()
    sub obj_eventhr()  ´在handles之后声明事件
        msgbox("事件处理器捕捉到了事件.")   ´处理事件.
    end sub
    sub main()
        addhandler obj.eventhr, addressof obj_eventhr
        obj.causesomeevent()   ´调用对象去引发事件
end sub
end module

“看到有什么不同吗?”大李转过身来问我。

“主要有两个不同,首先是obj的定义不再用withevents来标识了, 因此事件处理程序obj_eventhr()也就不能通过handles关键字来声明事件,也就 是说eventhr事件与事件处理程序没有用withevent-handles进行关联;其次,是 使用了addhandle和 addressof……”说到这,我也没有词了 ,只能语焉不详。

“呵呵,我来帮你接着说。”大李拍了拍我 的肩膀,接着说“先说addressof吧,addressof 运算符创建的是一个指向 指定的过程的过程委托。我们刚才说过委托相当于一个函数指针,那么addressof 就是委托的操作符,通过它能得到委托的引用。”

见到我稍稍明白 了,大李又接着说:“光看addhandle能够将obj.eventhr事件与 obj_eventhr事件处理程序关联起来的作法,你肯定不了解我所说的动态关联好处 在哪里。因为我没提到另一个方法removehandler。它的使用方法和addhandle是 一样的,比如:

removehandler obj.eventhr, addressof obj_eventhr

你看,addhandler 与 removehandler 在一起就可以提供比 handles 子句更大的灵活性,只要我们善于利用它们,就可以动态地添加、移除 和更改与某事件关联的事件处理程序。而且比 handles 要强大的是,addhandler 允许将多个事件处理程序与单个事件进行关联。”

大李停了一停, 接着说:“你要注意的一点就是addressof后面跟着的委托签名应该与相应 的事件数据类相一致,我们看一个例子。”

addhandler 

textbox.mousedown,addressof textboxmousedownhandler
‘错误的示例1:
private sub textboxmousedownhandler( )
end sub
‘错误的示例2
private sub textboxmousedownhandler(byval sender as object, byval e as 

eventargs)
end sub
‘正确的示例:
private sub textboxmousedownhandler(byval sender as object, byval e as 

mouseeventargs)
end sub

“事件是一个文本框中的鼠标按下事件,我们不用自带的 标准关联事件处理方法,而用addhandler来实现,那么addressof之后相应的方法 的参数声明,应该与mousedown事件对应的事件的委托mouseeventhandler具有相 同的签名,也就是参数声明上要保持一致,一个object变量,一个 system.windows.forms.mouseeventargs变量。”

我到这一步才算明 白了个大概,事件处理程序可以通过addhandler和removehandler方法在我们需要 的时候动态地建立或断开事件与事件处理程序的关联关系。可是,对于大李刚说 的“事件的委托mouseeventhandler”,我还是不太理解。

相关热词搜索:

上一篇:VB.NET之旅(十五)―动态事件处理方法
下一篇:vb.net之旅(十三)―标准事件处理程序

分享到: 收藏