2011-06-09 10:58:13更新
只要把重载的selectrow函数中的setrow改为scrolltorow就可以很好的解决问题了 :)
在pb11.5中测试发现, scrolltorow总是可以正确的触发rowfocus事件,它不像setrow那样受到item的focus的影响
=========================================================================
2011.5.23更新
原文最初写于2009年10月, 在一年多之后, 发现了更多的细节, 重新补充一下:
下文中的关键是在selectrow函数中调用了setrow函数,以保存触发rowfocuschanged事件,但使用中在click一行时, 仍会有未触发rowfocuschanged事件的情况,也就是下文中的第一个目的未能真正实现。
具体的原因很有趣: 如果传给setrow的行的所有字段都无法获得focus, 那么setrow并不能使它成为当前行。如果在setrow之后立即调用getrow()就会发现“当前行”是第一个能够获得focus的行。
由于本人在用的修改后的代码相当笨拙, 就不贴出来现丑了
还有一个有趣的事情: 如果在retrieveend中调用getrow()会发现不论第一行能否获得focus, getrow()都返回1, 也就是当前行是第一行。
所以, 【当前行】是一个不太好定义的概念
============================================================
起因:单击不同的行时(clicked事件), 有时会触发不了rowfocuschanged事件.
正常情况下,单击不同的行会自动触发rowfocuschanged事件,但在特殊情况下,会触发不了该事件(原因在文章最后)
目的是:1.单击(clicked)事件要100%触发rowfocuschanged事件,
2.使用键盘上的"上下方向"键可以移动"选中行"(也就是高亮行)
由于在单击事件和pbm_dwnkey事件中都要用到selectrow(row,true), 因此覆盖了父类的selectrow函数
1.自定义数据窗口控件,继承自datawindow控件
2.重写该自定义对象的selectrow函数,使其覆盖"父"dw类的同名函数,当然,是在"父类"基础上进行扩充
public function integer selectrow (long r, boolean f);
if f=true then
setrow(r)
end if
super::function selectrow(r,f)
return 1
end function
3.在该自定义对象中添加ue_key事件(pbm_dwnkey),处理"上下方向"键的事件,
//以下是本文关键:
由于前述selectrow函数中执行了setrow(r),
因此在执行selectrow函数后要return 1,否刚会引发两次"rowfocuschanged"事件,
且导致第二次rowfocuschanged的参数currentrow 不正确
event ue_key pbm_dwnkey
event ue_key;
long row
row=this.getselectedrow(0)
if row=0 then
return 0
end if
choose case key
case KeyDownArrow!
if row=this.rowcount() then
return 0
else
this.selectrow(row,false)
this.selectrow(row+1,true)
scrolltorow(row+1)
return 1
end if
case KeyUpArrow!
if row=1 then
return 0
else
this.selectrow(row,false)
this.selectrow(row - 1,true)
scrolltorow(row - 1)
return 1
end if
end choose
end event
当然clicked事件中就少不了selectrow(0,false);selectrow(row,true).
至于clicked事件不能100%触发rowfocuschanged事件,原因很简单,
在grid中, 列对象的高度默认是小于行高的:如列对象高度72,行高88
那列对象的上下各有8个pb单位的空隙, 当用户的鼠标刚好点在这
空隙上时,就会导致"当前行"未变,而这时的高亮行已经变了