我 们 在 数 据窗 口 中 需 要 进 行 行 选择 操 作。 如 用 户 为 了 修 改 数 据 或看 到 更 详 细 的 内 容 而 选 择 了 某 一 行; 在 另 一 些 情 况下, 用 户 可 能 要同 时 删 除 或 修 改 多 行, 这 时, 我 们 需要 有 使 用 户 在" name="description" />

在数据窗口中进行行选择操作

发表于:2007-05-25来源:作者:点击数: 标签:中进行行操作窗口选择
MI LY: 宋体"> 我 们 在 数 据窗 口 中 需 要 进 行 行 选择 操 作。 如 用 户 为 了 修 改 数 据 或看 到 更 详 细 的 内 容 而 选 择 了 某 一 行; 在 另 一 些 情 况下, 用 户 可 能 要同 时 删 除 或 修 改 多 行, 这 时, 我 们 需要 有 使 用 户 在

MILY: 宋体">       我 们 在 数 据窗 口 中 需 要 进 行 行 选择 操 作。 如 用 户 为 了 修 改 数 据 或看 到 更 详 细 的 内 容 而 选 择 了 某 一 行; 在 另 一 些 情 况下, 用 户 可 能 要同 时 删 除 或 修 改 多 行, 这 时, 我 们 需要 有 使 用 户 在 一 个 数 据 窗 口 中 同 时 选 择 多 行 的 功 能。这 在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")

       在 这 个 祖 先函 数 中 编 写 这 样 一 个 行 选 择 的 函 数 只 是 作 为 一 个 简单 的 实 例, 相 信 您 一 定 能 因 此 收 到启 发, 编 写 出 更 多的 函 数, 以 拓 展 数 据 窗 口 的 基 本 功 能。

 

原文转自:http://www.ltesting.net