資料視窗用鍵盤上的"上下方向"鍵移動選中行, selectrow函式觸發rowfocuschanged事件
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單位的空隙, 當用戶的滑鼠剛好點在這
空隙上時,就會導致"當前行"未變,而這時的高亮行已經變了