1. 程式人生 > >資料視窗用鍵盤上的"上下方向"鍵移動選中行, selectrow函式觸發rowfocuschanged事件

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