Windows Form中事件的激发顺序

前几天看周爱民先生的《大道至简--软件工程实践者的思想》(http://www.doany.net/)时看到书中谈到Windows的事件激发顺序,以及对其他过程的影响的问题,今天就不期然遇到一个大概类似的问题。

这些天写的一个系统,晚上发现偶尔会有不期然的事情发生:在执行一个数据库查询后返回的结果不一致,很是奇怪。初始代码是VB6,流程很简单,一个窗体有一个查询的方法,大概如下的代码:

Public Sub RefreshDb(strSQL As String)
    '记录结果的集合
    Set c = New Collection
DBQuery:  
    '查询代码
    ...
End Sub

方法查询的时候将结果的一部分写入集合c,供后续其他操作使用,并同时填充查询结果到一个Grid界面。在窗体的Load方法里也调用了这个方法,得到缺省的结果。

在VB6下,如果窗体没有初始化,调用顺序是:
(1)执行RefreshDb在“DBQuery:”之前的代码;
(2)调用Form的Load事件;
(3)等Load事件中的代码执行完毕后返回来执行“DBQuery:”之后的代码。

因此由于集合c没有New,调用RefreshDb的过程中中断了执行,调用了Load事件(其中又调用了RefreshDb),然后再回来,导致了结果不一致。

按照想法,要么是先执行Load事件,要么是先执行RefreshDb这个方法,然后调用Load事件(在VB.net 2005下是这样),但VB 6下,Load事件应该是在窗体显示或者窗体的某个变量第一次初始化时调用,上面代码中因为调用了对集合的初始化,因此执行了Load事件。VB 6的Load事件有构造函数的一些含义,而VB.net则完全是面向对象,New为构造函数,Load是窗体显示前的一个事件。对于VB 6程序员,这些差别应该注意。反过来,对于这个问题,如果是.net下的顺序,那么问题也很容易发现 :)。

正确的方法是先初始化窗体,例如调用Show或者Activate(.net,VB下为Show和SetFoucs)方法,然后调用RefreshDb,或者启动后就将该窗体初始化。因此开发中,窗体的事件激发顺序必须明确,否则会造成不必要的麻烦;第二,个人觉得,除非必要,例如项目要求或者平台的一些限制(包括硬件),VB 6程序员是抛弃老平台的时间了。

posted on 2005-12-13 16:02  马维峰  阅读(4907)  评论(1编辑  收藏  举报