|
深入理解Visual Foxpro 6.0 的事件模型
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
作 者 : 冯惠军 一、Visual Foxpro的核心事件 Visual Foxpro为程序对象定义了许多事件来完成程序的功能,多数对象都具有以下核心事件:
事件代码表示事件发生时所要执行的命令或程序,要放在相应的对象事件中,当该对象事件触发时就会执行该事件内的代码,来完成预定的功能。 编写事件代码时,需要注意两条规则: (1)每个对象的事件触发是独立的,容器对象(如窗体、选项组等)不能处理它所包含的对象的事件。例如,在窗体上放置一个命令按钮。当点击命令按钮时,不会执行窗体的Click事件,而仅执行命令按钮的Click事件。 (2)如果某个对象事件没有相应的事件代码,则系统会逐层向上检查其父类是否有与此事件相关的事件代码,若有则执行,而该层以上的与此事件相关的代码不会被执行。若该对象有事件代码,则系统只执行它的代码,而不会再向它的上层去寻找相应的事件代码,即不会再执行其父类的事件代码。但可以在该对象的事件代码中使用Dodefault( )函数,强制执行其父类的事件代码。 二、事件发生的顺序 当一个对象事件发生时,可能会引起其它事件的发生,因此,理解事件发生的顺序也是非常重要的。观察事件执行顺序的简单方法是在Debuuger工具中设置事件跟踪开关,这样,程序执行过程中的事件执行顺序就会显示在Debugger的事件跟踪窗口中。下面我们用一个例子来说明事件执行的顺序。在Visual
Foxpro中新建一个窗体Form1,加入两个文本框Text1、Text2,和两个命令按钮Cmd1、Cmd2,TAB键次序为Text1、Text2、Cmd1、Cmd2,如下图所示。
打开Visual Foxpro的Debugger窗口(Tools/Debugger),在Debugger窗口中选择Tools/Event
Tracking...,弹出Event Tracking...对话框,如下图所示。
设置要跟踪的事件,OK,然后打开Debug Output窗口(Window/Output)。回到Visual Foxpro运行上面建立的窗体,事件执行过程会显示在Debug
Output窗口中,如下图所示。
从上图可以看出,运行窗体时,事件的执行顺序为:
下面的事件是去察看Debugger窗口时发生的。窗体运行以后,如果在Text1中输入数据,则会交替执行KeyPress和InteractiveChange事件,如果输入完毕,按Enter或TAB键,则执行Text1的KeyPress事件,然后执行Valid事件,最后执行LostFocus事件。 下面我们来看看关闭窗体时事件执行的顺序。假设单击Cmd1关闭窗体, 则事件执行的顺序为:
三、得到和失去焦点 在应用程序开发中,窗体通常是用户对数据进行操作的界面。通常利用文本框、选择框、列表框等控制对象来显示、输入或修改数据库中的数据。有效的控制数据编辑的流程、数据对象焦点的转移,是建立用户友好的应用程序的重要部分。窗体中默认的对象之间焦点的转移是按照所设定的TAB次序进行的,但多数情况下,这种默认的次序往往满足不了应用的需要。比如说,我们可能要根据用户的选择来决定焦点要转移到哪个对象,而不是按照TAB的次序来转移焦点。如果不理解Visual Foxpro如何来控制对象的焦点,就会感到处理流程不容易控制。 涉及焦点的事件有四个,它们是:When、GotFocus、Valid、LostFocus和一个方法SetFocus。当对象试图得到焦点时,会先执行When事件,如果When事件返回真(.T.),该对象就会得到焦点,否则不会得到焦点。因此,在When事件中编写事件代码,来控制是否让该对象得到焦点。 但是,ListBox和ComboBox两个控制对象对When事件的响应有些不同。在这两个控制中,每次用鼠标或箭头键在列出的项目之间移动时都会执行When事件。因此,如果需要编写着两个控制的When事件代码,需要特别注意它们的差别。 失去焦点的过程与得到焦点的过程类似,当一个对象要失去焦点时会先执行Valid事件,如果Valid事件返回真(.T.),该对象就会失去焦点,并执行LostFocus事件,否则该对象不会失去焦点。Valid事件还可以返回整数值,如果返回0,对象不会失去焦点;如果返回正整数值,焦点会转移到整数值所指定的往下第几个对象;如果返回负整数值,焦点会转移到整数值所指定的往上第几个对象。因此,可以在Valid事件中编写事件代码来判断输入值是否有效,设定返回值是真还是假,来决定是否允许控制对象失去焦点。 还有一个命令可用于控制对象焦点的转移,NoDefault,这条命令可阻止Visual Foxpro执行事件默认的行为。例如在用文本框输入数据时,如果按Enter键,文本框会失去焦点,焦点会转移到下一个对象。如果不想让文本框失去焦点,可在文本框的KeyPress事件中插入一条NoDefault命令,按Enter键文本框也不会失去焦点。如果在NoDefault后面再加一条SetFocus命令,焦点就会转移到你需要的对象上去。 四、何时更新数据 Visual Foxpro是一个数据库应用开发环境,它提供了许多功能强大易于使用的数据绑定能力。多数控制对象都可以通过设置它的ControlSource属性与数据表的特定字段绑在一起,这样当控制对象的值发生改变时,会自动更新ControlSource所指定的数据字段的值。 但是值的更新也是发生在某个特定时刻,明确理解数据值更新何时发生,对于灵活运用控制对象实现预定的功能是很有帮助的。在Visual Foxpro中,控制对象更新它的ControlSource值是在Valid事件触发之前的时刻发生的,如果Valid事件没有触发,ControlSource的值不会更新。前面我们已经解释过,Valid事件的触发是在控制对象试图失去焦点时发生,我们通常是在Valid事件中检查输入值的有效性,但即使判断值是无效的,不让控制失去焦点,但由于触发了Valid事件,因此,ControlSource的值也已经改变了。下面我们做一个简单的测试,观察一下数据值变化的情况。建立一个窗体,放一个文本框,文本框的ControlSource属性设置为数据表的某一个字段。假设该字段原来的值是“OLD”,我们要把它改为“NEW”,用Debugger工具跟踪数据变化过程。在文本框的Gotfocus事件中加入下面的代码: DebugOut "Event Name: Gotfocus ControlSource: "; + Evaluate(This.ControlSource) + " Value: " + This.Value 同样,在文本框的InteractiveChange、KeyPress、Valid和LostFocus事件中都加上上面的代码,只是要把事件名GotFocus换成相应的事件名称。 打开Debug Output窗口,运行建立的Form,文本框中将显示“OLD”,输入“NEW”,然后按TAB键使文本框失去焦点,然后察看Debugger的Output窗口,将显示如下结果:
1说明如下:
从上表可以看出,存在一个时间段,ControlSource的值和文本框的Value值是不相同的。如果在这个时间内刷新文本框(即执行Refresh方法),则文本框的值就会恢复为ControlSource的当前值,这是在编写应用程序代码时需要注意的。 转载自Chinabyte网络学院
|