下拉列表是在窗口中定义的一个控件,与之相应的事件如下表所示:
表1 下拉列表控件上的事件
事件名称 触发时机
Constructor 在窗口中的OPEN事件发生前触发
Destructor 在窗口中的CLOSE事件发生后触发
Doubleclicked 当下拉列表控件(选中且激活)被双击时触发
Dragdrop 当一个可拖动控件到达下拉列表控件时触发
Dragenter 当一个可拖动控件进入下拉列表控件时触发
Dragleave 当一个可拖动控件离开下拉列表控件时触发
Dragwithin 当一个可拖动控件在下拉列表控件内部时触发
Getfocus 正在下拉列表控件获得焦点之前(它被选中且成为有效以前)触发。
Lostfocus 当下拉列表控件失去焦点时触发
Modified 当下拉列表控件失去焦点,同时下拉列表控件的文本内容已被更改,且按动了ENTER或TAB时触发
Other 当一个WINDOWS信息发生非PowerBuilder事件(例如,用户按动了鼠标中间的键)时触发
Rbuttondown 当用户在下拉列表空间中按动鼠标右键时触发
Selectionchanged 当选中下拉列表控件的某一项时触发
当选中下拉列表控件的某一项时,不仅触发Selectionchanged事件,还会触发Modified事件。
2 动态使用下拉列表
传统的下拉列表使用是静态的,它在一定程度上满足了编程的需要,但是不能满足所有需要。例如,有时希望下拉列表中的选项在程序运行过程中可以变化,这用静态下拉列表定义选项是不能实现的,这就促使人们去思考如何使用动态下拉列表。有两种情况需要使用动态下拉列表。
1)下拉列表中的选项与数据库中某列的内容相关联②
实际应用中,在对数据库表中的数据按名称进行查询时,为了减少输入量,可以将库中某列的内容(如单位名称)列在下拉列表中供用户选择,这样既可以保证选中的项目一定是库中的项目,而且不用输入汉字;又使下拉列表的使用具有一定的灵活性,动态下拉列表选项的确定必须在下拉列表被使用之前进行,可以在下拉列表所在窗口的Open事件中确定,也可以在下拉列表的Getfocus事件中确定,相应的script为
string id,ic
int i-op=1
declare c1 cursor for
select hotelid from hotelid-dangan using SQLCA;
open c1;
fetch c1 into: id;
do while sqlca.sqlcode=0
select p1602 into :ic from p16 where p1601=:id using sqlca;
if finditem(ddlb-1,ic,1)=-1 then
ddlb-1.insertitem(ic,+i-op)
i-op=i-op+1
end if
fetch c1 into :id;
loop
close c1;
其中,下拉列表中的项目取自数据库表hotelid-dangan 的hotelid列所对应的p16表中的p1602(即单位名称)。
2)在下拉列表的使用过程中动态增加选项[1]
下拉列表中的选项在使用过程中有可能需要随时增加一些内容,例如:在“政治面貌”一列的下拉列表中包含党员、群众、团员。在运行过程中,发现有的人“政治面貌”为“民主党派”,此项不能从下拉列表中选择,但若“政治面貌”为“民主党派”的人很多,输入量就会增加,这时用户可能希望将“民主党派”送到下拉列表中以便于输入。处理方法:下拉列表控件定义为“可编辑”,下拉列表控件的Modified事件中编写script为
int i-file
i-file=totalitems(ddlb-1)
if ddlb-1.selectitem(ddlb-1.text,1)=0 then
insertitem(ddlb-1,ddlb-1.text,i-file)
end if
此种方法只能保证在一次运行过程中该项存在于下拉列表中,第二次重新进入该窗口后,下拉列表中的内容又恢复到定义时的状态。
3 在下拉列表中实现模糊查询
前述的查询方法中的选项来自于数据库,选项可能比较多,选择选项的时间也较长,解决这一问题可以通过模糊查询的方法。具体如下:
在下拉列表控件的Modified事件中编写script为
hotelcx-mc=ddlb-1.text string ic-tj
long in-pos
boolean empty-ddlb=false
if not (sele-modi ) then
string select-str
long ad-count
ad-count=totalitems(ddlb-1)
ic-tj=trim(ddlb-1.text)
do while ad-count>=0
ddlb-1.selectitem(ad-count)
select-str=ddlb-1.text
in-pos=pos(select-str,ic-tj)
if in-pos<>0 then
empty-ddlb=true
else
deleteitem(ddlb-1,ad-count)
end if
ad-count --
loop
if empty-ddlb=false then
messagebox(“提示信息",“没有满足条件的单位,请重新输入!")
string id-1,ic1 int i-op=1
declare c2 cursor for
select hotelid from hotelid-dangan using SQLCA;
open c2;
fetch c2 into :id-1;
do while sqlca.sqlcode=0
select p1602 into :ic1 from p16 &
where p1601=:id-1 using sqlca;
if finditem(ddlb-1,ic1,1)=-1 then
ddlb-1.insertitem(ic1,+i-op)
i-op=i-op+1
end if
fetch c2 into :id-1;
loop
close c2;
ddlb-1.text=""
setfocus(ddlb-1)
else
ddlb-1.showlist=true
ddlb-1.text=""
setfocus(ddlb-1)
end if
end if
sele-modi=false
其中:hotelcx-mc是一个shared变量,用来存放要进行模糊查询的条件;ic-tj是进行查询时用来与下拉列表中的选项进行比较的内容;in-pos用来存放每次比较的结果;empty-ddlb用来存放是否查到满足条件的单位名称,如果没有满足条件的单位,必须将下拉列表恢复到最多选项的状态;sele-modi是一个shared变量,用来屏蔽Selectionchanged事件,因为选择下拉列表中的选项后激活Selectionchanged事件,但此时不希望触发Modified事件,所以要屏蔽;select-str用来存放从下拉列表中取出的每一项;ad-count存放下拉列表中的总项数[2]。
在下拉列表控件的Selectionchanged事件中增加语句sele-modi=true(该事件中其他script代码与次数无关,故在此略去),以保证执行Selectionchanged事件中的语句之后不再执行Modified事件中的语句。另外,在窗口的Open事件中编写script为
string id,ic
int i-op=1
declare c1 cursor for
select hotelid from hotelid-dangan using SQLCA;
open c1;
fetch c1 into :id;
do while sqlca.sqlcode=0
select p1602 into :ic from p16 where p1601=:id using sqlca;
if finditem(ddlb-1,ic,1)=-1 then
ddlb-1.insertitem(ic,+i-op)
i-op=i-op+1
end if
fetch c1 into :id;
loop
close c1;
sele-modi=false
以上程序已通过调试,有兴趣的读者不妨一试。