主题:[转帖]表格的三个疑难问题-----可称作是补品了
一、焦点的转移:解决Grid的刷新问题
前言:
你也许碰到过这样的问题:你想用一个VCR按钮来移动表的指针,比如上一个、下一个等等,却发现Grid不刷新、老是停留在原来的位置;还有,你想在一个添加按钮的代码中把焦点移入表格的一列中,用setfocus()方法却根本没有反应。这是怎么回事呢?
更多的细节:
关于Gird中的控件的焦点转移有点特殊性。给普通表单上的控件设置焦点我们可以用简单的代码实现,比如:
thisform.textbox1.setfocus()
thisform.refresh()
但是Grid中的控件则不行,如果你使用以下的代码,什么都不会发生:
thisform.grid1.column1.text1.setfocus()
thisform.refresh()
同时,你要从Grid中移出焦点到表单的控件上也一样,下面的代码同样没有反应:
thisform.grid1.cloumn1.text1.lostfocus()
thisform.command1.setfocus()
thisform.refresh()
另外,当我们使用移动纪录按钮在表中移动时,并不会反映到Grid中,比如:
sele dbfname
go bottom
thisform.refresh()
而Grid仍然停在原来的记录上。这是怎么一回事呢?
原来,对Grid中控件焦点的移入移出,必须通过Grid来转移!这一点在所有的教科书、程序员手册中都找不到,嘿嘿,是我自己摸索出来的。下面我们来解决上面的三个问题:
1、从表单的命令按钮向Grid中的文本框设置焦点
thisform.grid1.setfocus()
thisform.grid1.column1.text1.setfocus()
thisform.refresh()
2、从Grid中的文本框中移出焦点
thisform.grid1.column1.text1.lostfocus()
thisform.grid1.setfocus()
thisform.command1.setfocus()
thisform.refresh()
3、当数据指针移动时刷新Grid
sele dbfname
go bottom
thisform.grid1.setfocus()
thisform.refresh()
二、Vaild事件
有的朋友以为Grid没有Vaild事件,所以必须用AfterRowCowChange()事件来代替。其实
这种看法说明对面对对象编程原理的理解不够。我们知道,Grid是一个容器控件,它是由一
个容器和容器包含的多个Column控件组成;而Column控件也是一个容器控件,它是由一个容
器和容器包含的header、textbox控件组成的。了解了这一点,我们就可以知道Grid虽然没
有Vaild事件,但是Textbox当然是有这个事件的啊。我们只要从属性窗口顶部的对象下拉列
表框中选择表格中相应的列中的文本框控件,然后双击它的Vaild事件,输入相应的代码就
可以了。
三、Grid什么都不显示
在Grid的数据源变化的情况下(数据源为参数化视图的情况除外),刷新时会出现Grid上什
么都没有、甚至连列/表格线都消失的情况,我不知道这算是VFP的一个特点还是一个BUG。起
初,我通过用代码方式重新生成表单的方法来解决,后来经人指点才发现,可以简单的用代
码重新指定数据源的方法来解决,这个问题在MSKB里专门有一篇HOWTO。
例如:
Grid的数据源为一个SQL语句生成的视图MyView,Grid1的数据源设置为MyView,如果
是查询字段不变的参数化视图,不会发生这种情况;但如果查询字段发生了变化,则必须在
改变了SQL语句后用代码重新指定Grid的数据源,代码如下:
MyView视图的原来条件为:
select * from 数据库名!表名 where 表名.字段一 = ?thisform.qryValue
Grid1.RecordSourceType为视图;
Grid1.RecordSource=MyView
现在,我根据用户的选择/输入生成新的视图:
Create sql View MyView as (select * from 数据库名!表名 where 表名.字段二 = ?thisform.qryValue)
thisform.grid1.recordsource=MyView &&注意,这是重点
=Requery()
thisform.refresh()
这样就可以解决问题了。