p align="center">在數(shù)據(jù)窗口中使用滾動條
在數(shù)據(jù)窗口中,我們總不可避免要使用到滾動條。在缺省狀態(tài)下,當(dāng)用戶點(diǎn)擊垂直滾動條時,當(dāng)前的數(shù)據(jù)窗口滾動顯示一頁或一行新內(nèi)容,可是有時我們希望在用戶點(diǎn)擊滾動條時,系統(tǒng)有另外的響應(yīng)。在數(shù)據(jù)窗口的事件中,全局變量message中wordparm屬性指示了是何種滾動類型導(dǎo)致了這個事件的發(fā)生。
WordParm的值垂直滾動類型
0行向上滾動
1行向下滾動
2頁向上滾動
3頁向下滾動
4豎直移動
通過判斷這些滾動類型,我們就可以改變它的缺省動作,工對滾動方式進(jìn)行控制。例如在某些情況下,我們希望用點(diǎn)擊滾動條時,記錄能夠一行一行的滾動。下列的代碼可以tabular、freeform和grid表現(xiàn)形式的數(shù)據(jù)窗口中,實(shí)現(xiàn)這樣的功。在數(shù)據(jù)窗口的OTHER事件中:
integerli_wordparmli_wordparm=Message.WodParmifMessage.
Number=277thenifli_wordparm=1orli_wordparm =3thn//捕捉行向下滾動和頁向下滾動的事件,使屏幕向下滾動一條記錄,并將數(shù)據(jù)窗口
//的聚焦向下移動一行dw_1.ScrollToRow(dw_1.GetRow()+1)elseifli_wordpar
m=0orli_wordparm=2then
//捕捉行向下滾動和頁向下滾動的事件,使屏幕向下
滾動一條記錄,并將數(shù)據(jù)窗口
//的聚焦向上移動一行dw_1.ScrollToRow(dw_1.GetRow
()-1)elseRETURNendif
//避免缺省的數(shù)據(jù)窗口的滾屏行為Message.Processed=
TRUEendif
在開發(fā)過程中,我們可能會大量的使用Master/Detal形式的數(shù)據(jù)窗口來表現(xiàn)數(shù)據(jù)。所謂Master/Detail風(fēng)格就是在一窗口中有兩個數(shù)據(jù)窗口組成主表和細(xì)目表,分別顯示數(shù)據(jù)中的兩張相關(guān)聯(lián)的表,這一格式可用于展現(xiàn)給定事物的兩數(shù)據(jù)的關(guān)系。
使用Master/Detail形式的一種可能性是使兩個數(shù)據(jù)窗口顯示同一套數(shù)據(jù),其中Master的數(shù)據(jù)用于瀏覽,不能修改,而Detail的數(shù)據(jù)窗口顯示的是與Master窗口的相關(guān)的更為詳細(xì)的信息,是可以修改的。這時您希望用戶只能夠滾動Master窗口,同時使Detail窗口顯示響應(yīng)的信息,而不希望用戶能夠使用滾動條來滾動Detail數(shù)據(jù)窗口,翻看無關(guān)的信息。
下面的代碼就是用于避免用戶滾動Detail數(shù)據(jù)窗口,翻看到其它行的? 。
事件名稱:Keypressed
描述:Keypressed為一個用戶自定義事件,在數(shù)據(jù)窗口控件的Script畫筆中定義,它的事件編號為pbm_dwnkey,當(dāng)用戶有按鍵操作時觸發(fā)。
Script:
IF(KeyDown(keytab!))OR(KeyDown(keyEnter!))OR
(KeyDown(keyDownArrow!))&
OR(KeyDown(KeyUpArrow!))OR(KeyDown(KeyPageDown!))
OR&
KeyDown(KeyPageUp!))&
THEN
This.SetRedraw(False)
//當(dāng)用戶按下上述鍵時,系統(tǒng)將不與響應(yīng),避免數(shù)據(jù)窗口
自動進(jìn)行相應(yīng)的操作
ENDIF
在上面的的事件中,我們使用了SetReDraw()函數(shù),這將阻塞用戶對數(shù)據(jù)窗口諸如更新等操作,我們必須在下列事件中取消用戶對數(shù)據(jù)窗口進(jìn)行正常操作的阻塞。
事件名稱:RowFocusChanged
Script:
This.ScrollToRow(myrow)
//myrow是一個實(shí)例變量,它的值是這個數(shù)據(jù)窗口當(dāng)前應(yīng)當(dāng)顯示的記錄數(shù)
This.SetRedraw(True)
//允許對數(shù)據(jù)窗口進(jìn)行操作
事件名稱:ItemFocusChanged
Script:
This.SetRedraw(True)
//允許用戶在同一條記錄內(nèi)進(jìn)行水平滾動
在有些情況下,我們會使Master和Detail兩個數(shù)據(jù)窗口顯示相同的內(nèi)容,我們可以使用ShareData()函數(shù)令Detail數(shù)據(jù)窗口共享Master窗口的數(shù)據(jù),如何在使用滾動條滾動其中的一個窗口時,另一個窗口能夠同步進(jìn)行滾動呢?如果您沒有對Master數(shù)據(jù)窗口使用RetrieveasNeeded選項(xiàng),這一個功能的實(shí)現(xiàn)是十分簡單的。
假設(shè)Master數(shù)據(jù)窗口名稱為dw_1,對其SCROLLVERTICAL事件編程如下:
integervmax_1,vpos_1,vmax_2,vpos_2
stringr_code
decimalvmax_1_percent
vmax_1=integer(dw_1.describe(datawindow.verticalscrollmaximum)) vpos_1=integer(dw_1.describe(datawindow.verticalscrollposition)) vmax_2=integer(dw_2.describe(datawindow.verticalscrollmaximum)) vmax_1_percent=vpos_1/vmax_1
vpos_2=vmax_1_percent*vmax_2
r_code=dw_2.modify(datawindow.verticalscrollposition=+string(vpos_2)) //檢驗(yàn)是否修改成功
ifr_codethen
beep(6)
mle_1.text=dw_1scroll=+r_code+vpos_2= +string(vpos_2)
//在scrollvertical事件中無法使用MessageBox彈出錯誤信息框
endif
Detail數(shù)據(jù)窗口名稱[qu1]為dw_2,對其SCROLLVERTICAL事件編程如下:
integervmax_1,vpos_1,vmax_2,vpos_2
stringr_code
decimalvmax_2_percent
vmax_2=integer(dw_2.describe(datawindow.verticalscrollmaximum)) vpos_2=integer(dw_2.describe(datawindow.verticalscrollposition)) vmax_1=integer(dw_1.describe(datawindow.verticalscrollmaximum)) vmax_2_percent=vpos_2/vmax_2
vpos_1=vmax_2_percent*vmax_1
r_code=dw_1.modify(datawindow.verticalscrollposition=+string(vpos_1)) //檢驗(yàn)是否修改成功
ifr_codethen
beep(6)
mle_1.text=dw_1mod+r_code
endif
談到這里,我們又要引入一個新話題,這就是在某些事件中避免使用MessageBox的問題:當(dāng)用戶進(jìn)行的錯誤操作時,我們應(yīng)當(dāng)在屏幕上彈出一個提示框,警告發(fā)生的錯誤或提示將要發(fā)生的事情,以引起用戶的注意;有些程序員也喜歡在調(diào)試程序時,使用MessageBox函數(shù)顯示當(dāng)前的系統(tǒng)狀態(tài)??墒窃赑owerBuilder的某些改變控件聚焦的事件中,系統(tǒng)是無法顯示信息框的,我們必須使用response類型的窗口來取代信息框:在這些事件中使用POST方式調(diào)用一個新事件,在新事件中打開這個response窗口。
某些窗口控件(包括按鈕在內(nèi))是由于聚焦的改變而捕獲鼠標(biāo)的,在這些控件的某些事件中應(yīng)避免使用MessageBox函數(shù)的。這些事件包括這樣幾類:
1.事件名稱:
Modified
GetFocus
LoseFocus
ItemFocusChanged
Activate
Deactivate
不能使用的原因:由于聚焦的改變而導(dǎo)致循環(huán)。
2.事件名稱:
ScrollVertical
ScrollHorizontal
ScrollBar對象
不能使用的原因:MessageBox將導(dǎo)致消息隊(duì)列的過載,不要在任何卷滾的事件中使用MessageBox函數(shù)。
3.事件名稱:
ReSize
不能使用的原因:當(dāng)用戶點(diǎn)擊MessageBox的OK框后,父窗口將重新獲得聚焦,并再次觸發(fā)resize事件,彈出另外的一個MessageBox,這將導(dǎo)致無窮循環(huán)。
4.事件名稱:
Open(Response窗口)
不能使用的原因:這將在打開窗口時同時有多個窗口模板,從而導(dǎo)致了不可預(yù)料的結(jié)果。
此外,MessageBox還將觸發(fā)Activate或Deactivate事件。因此有些情況下,您可以將信息寫在窗口的標(biāo)題、微幫助上,或是使用單行編輯器,使用Beep()函數(shù)有時也可以達(dá)到指示作用,而不必須非使用MessageBox不可。
我們言歸正傳,當(dāng)Master數(shù)據(jù)窗口沒有使用RetrieveasNeeded選項(xiàng)時,上面的代碼就可以得到滿意的結(jié)果,而如果您為了得到更快的響應(yīng)速度而使用了Retrieveas Needed時,結(jié)果就沒有這么簡單了。在用戶點(diǎn)擊dw_2的滾動條使之滾動到最下部時,因數(shù)據(jù)窗口已將數(shù)據(jù)顯示到了最后一條,這就觸發(fā)dw_1從后臺數(shù)據(jù)庫中攫取新的數(shù)據(jù),這樣當(dāng)dw_1數(shù)據(jù)窗口中有了新數(shù)據(jù),系統(tǒng)會自動發(fā)出消息,使共享數(shù)據(jù)的dw_2復(fù)位,滾回到最初的位置。這樣將觸發(fā)了dw_2的scrollvertical事件,使dw_2和dw_1均滾回到初始的位置,因而無法得到正確的結(jié)果。如何解決這個問題呢?有興趣的讀者可以簡單思考一下,我們將在下期對這一問題進(jìn)行進(jìn)一步的討論。