在數據窗口中進行行選擇操作
2024-07-21 02:06:05
供稿:網友
我 們 在 數 據窗 口 中 需 要 進 行 行 選擇 操 作。 如 用 戶 為 了 修 改 數 據 或看 到 更 詳 細 的 內 容 而 選 擇 了 某 一 行; 在 另 一 些 情 況下, 用 戶 可 能 要同 時 刪 除 或 修 改 多 行, 這 時, 我 們 需要 有 使 用 戶 在 一 個 數 據 窗 口 中 同 時 選 擇 多 行 的 功 能。這 在powerbuilder 中 是 相 當 容 易 做 到 的, 但 是, 如 果 您 在 一個 數 據 窗 口 祖 先 中 沒 有 標 準 的 函 數 來 處 理 這 些, 而 在每 個窗 口 中 重 復 的 編 程, 這 當 然 就 要 麻 煩 多 了。
我 們 首 先 來看 一 看 進 行 行 選 擇 的不 同 方 法。
所 有行 都 不 加 亮
數 據 窗 口 的標 準 行 為 是 不 加 亮 任 何 行。 這 當 然 實 現 起 來 很 簡 單了, 您 什 么 也 不 需 要 做。 這 種 做 法 對于 那 些 只 允 許 用戶 進 行 滾 動 和 查 看 的 數 據 列 表 或 那 些 單 行 的 數 據 窗口 是 合 適 的。
單 行選 擇
單 行 選 擇 意味 著 用 戶 在 同 一 時 間 只 能 選 擇 一 行。 在 用 戶 選 擇 一 行來 執 行 一 些 動 作, 如 刪 除 或 是 在主 從 關 系 的 列 表 中 顯示 詳 細 信 息, 這 是 非 常 有 用 的。 下 面 是 實 現 允 許 單 行選 擇 功 能 所 應 編 寫 的 代碼:
event: rowfocuschanged
if getrow() > 0 then
selectrow( 0, false )
selectrow( getrow(), true )
end if
多 行的 自 動 選 擇
多 行 的 自 動選 擇 時, 當 用 戶 點 擊 一 個 未 加 亮 的 行 時, 該 行 將 變亮。 如 果 用 戶 點 擊 一 個 加 亮 行, 該 行將 不 加 亮。
為 了 實 現 上述 行 為, 您 可 以 將 以 下 的 代 碼 放 入rowfocuschanged 事 件 中:
event:rowfocuschanged
event: rowfocuschanged
object: any datawindow
if getrow() > 0 then
if isselected( getrow() ) then
selectrow( getrow(), false )
else
selectrow( getrow(), true )
end if
end if
或者簡化成為下面的一行代碼:
if getrow() > 0 then selectrow( getrow(), not isselected( getrow()))
按住shift,control或control+shift點擊鼠標的使用
windows 的 文 件 管 理 器 或 其 它windows 程 序 中, 您 可以 使 用 按 住shift,control 或control+shift 這 種 鍵 盤與 鼠 標 的 組 合 來 改 變 選 擇 行 為。powerbuilder 在 數 據 窗 口 中沒 有 提 供 這 樣 的 能 力, 我 們 必 須 自 己 實 現。
我 們 應 當 實 現 的 組 合 功 能 是:
按 下 鍵
動 作
無
只 加 亮 當 前 行, 將 其 它 行 的 顯示 設 為 正 常
control
保 持 其 它 行 的 狀 態, 并 將 當 前行 也 加 亮
shift
加 亮 起 始 行 至 當 前 行 之 間 的 所有 行, 將 其 它 行 的 顯 示設 為 正 常
control-shift
保 持 其 它 行 的 狀 態, 并 加 亮 起始 行 至 當 前 行 之 間 的 所有 行,
建 立 這 樣 的 功 能, 我 們 首 先 需要 對 起 始 行 進 行 跟 蹤。在 用 戶 使 用shift 或control-shift 鍵時, 系 統 應 當 把 當 前 用 戶 用 鼠 標 點 擊 或 鍵 盤 選 中 的 行與 在 此之 前 進 行 操 作 的 起 始 行 之 間 的 所 有 行 全 部 加亮。 因 此, 數 據 窗 口 必 須 記 錄 當 前 的 起 始 行。 我 們 聲明這 樣 一 個 實 例 變 量:
protected long il_anchor_row
當 用 戶 點 擊 鼠 標 或 進 行 了 鍵 盤操 作 時, 我 們 要 測 試 用戶 是 否 同 時 按 下 了shift 或control 鍵, 使 用 的 是keydown() 函 數, 檢 查 有 沒 有keyshift! 和keycontrol!,如有 這 樣 的 鍵 按 下 則 記 錄 起 始 行。
編 寫行 選 擇 函 數
為 了 在 用 戶點 擊 鼠 標 或 進 行 鍵 盤 操 作 時 使 上 述 行 為 發 生 作 用, 我們 必 須 在clicked 事 件 和 一 個 映射 到pbm_dwnkey 事 件 的 自 定 義用 戶 事 件 中 調 用 我 們 自 己 的 行 選 擇 函 數。 這 樣, 不 管用 戶 是 點 擊 鼠標 還 是 擊 中 鍵 盤, 選 擇 行 為 都 會 發 生。您 也 可 以 將 這 個 功 能 放 入rowfocuschanged 事 件 中。
為 了 使 這 個 行 選 擇 功 能 可 重用, 這 里 我 們 建 立 兩 個 函數。 一 個 函 數 設 置 我 們 希 望的 選 擇 行 為 類 型, 另 外 一 個 真 正 執 行 該 選 擇 行 為。 首先 我 們 使 用 一 個 實例 變 量 來 設 定 選 擇 行 為 的 值:
protected integer ii_select_behavior
這 個 變 量 中 將 存 放 下 面 的 一 些值。
可 能 發 生 的 選 擇 行 為
值
行 為 0
不 允 許 選 擇 行 為 1
只 允 許 有 一 行 選 中 2
自 動 實 現 多 行 選 擇 3
允 許 使 用 鼠 標 和 鍵 盤 組 合 選 擇 99
不 允 許 選 擇, 將 鼠 標 變 成 手 型如 果 您 使 用 的 是 保 護 變量 或 私 有 變 量, 這 就 意 味 著 本對 象 以 外 的 程 序 無 法 訪 問, 因 此 您 必 須 為 其 他 程 序 員建 立 對 這 些 變量 賦 值 和 獲 取 這 些 變 量 值 的 函 數。 另外, 您 還 需 要 一 些 函 數 來 執 行 基 于 該 變 量 的 過 程。
函 數:uf_setselect(select_behavior)
我 們 要 寫 的 第 一 個 函 數 將 允 許程 序 員 設 置 選 擇 行 為。
函 數 : public integer uf_setselect( integer ai_select_behavior)
/* 本 函 數 設 置 數 據 窗 口 的 選 擇行 為 值
下 列 為 有 效 的 選 擇 行 為 值 */
choose case ai_select_behavior
case 0, 1, 2, 3, 99
ii_select_behavior = ai_select_behavior
// 至 少 一 行 將 被 選 中
if ai_select_behavior = 1 then
uf_process_select( getrow(), "keyboard" )
end if
if ai_select_behavior = 99 then
setrowfocusindicator(hand!)
else
setrowfocusindicator(off!)
end if
return 0
case else
return -1
end choose
函 數:uf_processselect(long al_row, string as_input_type)
一 旦 選 擇 類 型 被 設 置, 所 有 的行 都 必 須 被 處 理。 我 把這 部 分 代 碼 放 入 一 個 叫 作uf_processselect 的 函 數 中。 這 個 函 數 處 理 選 擇 行 為。 您 需 要 告 訴 該函數 您 想 要 處 理 的 行 和 該 請 求 是 通 過 鼠 標 還 是 鍵 盤 發出 的。 下 面 是 該 函 數:
long l_row
boolean b_reset_anchor
boolean b_keyboard, b_mouse
// 鼠 標 動 作 還 是 鍵 盤 動 作 ?
if upper(left(as_input_type,1)) = "k" then
b_keyboard = true
else
b_mouse = true
end if
/* 確 認 鼠 標 點 在 了 數 據 窗 口 的 記 錄 上 */
if al_row <1 then return 1 /* 是 否 要 確 定 起 始 行 */ b_reset_anchor="true" setredraw(false) /* 有 效 的 操 作 值 0="不" 允 許 選 擇 行 為 1="只" 允 許 有 一 行 選 中 2="自" 動 實 現 多 行 選 擇 3="允" 許 使 用 鼠 標 和 鍵 盤 組 合 選 擇 99="不" 允 許 選 擇, 將 鼠 標 變 成 手 型*/ choose case ii_select_behavior case 0, 99 // 無 case 1 // 單 行 選 中 selectrow(0,false) selectrow(al_row,true) case 2 // 多 行 選 中 if b_mouse then selectrow(al_row, not isselected( al_row )) end if case 3 if keydown(keyshift!) and keydown(keycontrol!) then if il_anchor_row> al_row then
for l_row = il_anchor_row to al_row step -1
this.selectrow(l_row,true)
next
else
for l_row = il_anchor_row to al_row
this.selectrow(l_row,true)
next
end if
elseif keydown(keyshift!) then
selectrow(0,false)
if il_anchor_row > al_row then
for l_row = il_anchor_row to al_row step -1
this.selectrow(l_row,true)
next
else
for l_row = il_anchor_row to al_row
this.selectrow(l_row,true)
next
end if
b_reset_anchor = false
elseif keydown(keycontrol!) then
selectrow( al_row, not isselected( al_row ) )
else
selectrow(0,false)
selectrow(al_row,true)
end if
end choose
setredraw(true)
if b_reset_anchor then il_anchor_row = al_row
return 0
現 在, 當 我們 希 望 執 行 行 選 擇 時, 所 要 做 的 全 部 操 作 就 是 調 用uf_processselect() 函 數。 一 般 當用 戶 在 一 個 數 據 窗 口 中 點 擊 了 鼠 標 或 是按 下 了 上、 下 箭 頭 鍵 時, 調 用 這 個 函 數。 另 外 還 有 捕獲home 和end 鍵 的 代 碼。 下 面 是we_keydow 用 戶 事 件( 映 射 到pbm_dwnkey 事 件) 中 的 代 碼:
event: we_keydown (pbm_dwnkey)
object: any datawindow
if keydown(keydownarrow!) and getrow() <> rowcount() then
uf_processselect( getrow() + 1 , "keyboard")
elseif keydown(keyuparrow!) and getrow() <> 1 then
uf_processselect( getrow() - 1 , "keyboard")
elseif keydown(keyhome!) and rowcount() > 0 then
uf_processselect( 1, "keyboard")
elseif keydown(keyend!) and rowcount() > 0 then
uf_processselect( rowcount(), "keyboard")
end if
最 后, 我 們 需 要 在clicked 事 件 中 加 入:
uf_processselect(getclickedrow(), "mouse")
在 這 個 祖 先函 數 中 編 寫 這 樣 一 個 行 選 擇 的 函 數 只 是 作 為 一 個 簡單 的 實 例, 相 信 您 一 定 能 因 此 收 到啟 發, 編 寫 出 更 多的 函 數, 以 拓 展 數 據 窗 口 的 基 本 功 能。