Database 版 (精华区)

发信人: lizhenguo (夸父·追日), 信区: Database
标  题: 31
发信站: 哈工大紫丁香 (2001年09月26日18:47:10 星期三), 站内信件

 bbs.hit.edu.cn
PowerBuilder专栏
[回到开始][上一层][下一篇]
----------------------------------------------------------------------------
----
发信人: carsam (独自偷...), 信区: Database
标 题: PowerBuilder应用开发系列讲座(31)
发信站: 逸仙时空 Yat-sen Channel (Wed Jan 5 12:35:18 2000), 站内信件
PowerBuilder应用开发系列讲座(31)
----------------------------------------------------------------------------

----
在数据窗口中使用滚动条(续)
   在 上 期 中 我 们 讨 论 了 在Master/Detail 数 据 窗 口 中, 当Master 数

据 窗 口 没 有 使 用"Retrieve as Needed" 选 项 时, 两 个数 据 窗 口 同 时
滚 动 的 问 题。 可 是 当Master 数 据 窗 口 使 用 了"Retrieve as Needed" 选
项 时, 我 们 却 遇 到 了 麻 烦。 在 点 击dw_2 的 滚动 条 时, 如 果dw_1 从
数 据 库 中 取 得 了 新 数 据, 将 导 致dw_2 的复 位,dw_2 就 不 能 显 示 正

确 的 结 果 了。 解 决 这 个 问 题, 我 们最 容 易 想 到 的 解 决 方 法 就
是 利 用dw_2 在scrollvertical 事 件 中获 得 的dw_2 当 前 滚 动 条 的 位 置,

对dw_2 进 行 重 新 赋 值。
   即 对dw_1 的SCROLLVERTICAL 事 件 编 程 如 下:
integer vmax_1, vpos_1,vmax_2, vpos_2
string r_code
decimal vmax_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))
// 检 验 是 否 修 改 成 功
if r_code <> "" then
beep(6)
mle_1.text = "dw_1scroll = "+r_code+" vpos_2 = "+string(vpos_2)
//在scrollvertical事件中无法使用MessageBox弹出错误信息框
end if
对dw_2 的SCROLLVERTICAL 事 件 编 程 如 下:
integer vmax_1, vpos_1,vmax_2, vpos_2
string r_code
decimal vmax_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))
// 检 验 是 否 修 改 成 功
if r_code <> ""then
beep(6)
mle_1.text = "dw_1 mod "+r_code
end if
r_code = dw_2.modify("datawindow.verticalscrollposition="+string(vpos_2))
// 检 验 是 否 修 改 成 功
if r_code <> "" then
beep(6)
sle_1.text = "dw_2 mod" + r_code
end if
   键 入 上 述 代 码 后, 运 行 时 你 就 会 发 现 点 击dw_2 时 运行 的 结
果 是 正 常 的, 然 而 点 击dw_1 的 滚 动 条 却 发 生 了 错 误。这 是 为 什
么 呢 ?
   首 先 我 们 还 是 对 用 户 点 击dw_1 的 滚 动 条 向 下 滚 动 时,系 统
进 行 了 哪 些 操 作 进 行 一 下 仔 细 地 分 析: 当 用 户 点 击鼠 标 使dw_1

滚 动 到 了 最 后 一 行 时, 这 时 系 统 没 有 立 即 进 行显 示 滚 动 的 操
作, 它 首 先 发 现 数 据 窗 口 的Primary! 缓 冲 区 的数 据 已 经 告 罄, 于

是 就 向 后 台 的 数 据 库 中 攫 取 数 据, 取 得新 的 数 据 后, 系 统 会
将 与dw_1 共 享 数 据 的dw_2 复 位, 使 之 回到 显 示 第 一 条 记 录 的 位 置

。 这 就 触 发 了dw_2 的scrollvertical 事 件( 我 们 称 之 为 事 件 一)。 在

这 个 事 件 中, 由 于 此 时dw_2 显 示 的 是 第 一 条 记 录, 它 将 修 改dw
_1 的 滚 动 条 位 置, 使 之也 显 示 第 一 条 记 录。 并 立 即 触 发dw_1 的s

crollvertical 事 件 二。在 事 件 二 中,dw_1 又 根 据 自 己 的 位 置 修 改dw

_2, 但 是 由 于dw_2 修 改 前 后 的 位 置 相 同, 所 以 没 有 对 系 统 造 成

什 么 影 响, 又回 到 了 事 件 一。 在 事 件 执 行 完 毕 后, 系 统 开 始 响

应 用 户 的下 滚dw_1 的 操 作, 首 先 将dw_1 向 下 滚 动 一 条 记 录, 这 样

dw_1 显示 的 是 第 二 条 记 录, 并 触 发 了dw_1 的scrollvertical 事 件 三。

当事 件 三 执 行 时, 将dw_2 也 滚 动 到 第 二 条 记 录, 并 触 发 了dw_2 的

scrollvertical 事 件 四, 不 过 这 一 事 件 四 也 不 会 对 任 何 一 个数 据
窗 口 造 成 影 响, 最 后 返 回 执 行 完 事 件 三。 这 就 完 成 了用 户 点 击

鼠 标 后 的 一 连 串 响 应。 但 是 最 后 两 个 数 据 窗 口却 显 示 的 是 第
二 条 记 录。 有 兴 趣 的 读 者 可 以 仔 细 分 析 这一 系 列 事 件 发 生 的
顺 序。
   用 户 点 击 滚 动 条 而 使 得 上 述 代 码 对 各 个 事 件 触 发及 其 执
行 过 程 虽 然 十 分 复 杂, 并 不 是 每 一 个 人 都 有 兴 趣对 其 分 析 清
楚, 但 是 这 个 代 码 的 错 误 却 是 一 目 了 然 的, 只须 稍 加 测 试 就 可

发 现。 可 是 令 人 不 解 的 是 这 段 代 码 在 美国 却 几 乎 被 视 作 经 典
, 而 且 向 美 国PowerSoft 技 术 支 持 中 心提 出 这 个 问 题, 那 里 的 工
作 人 员 也 会 引 用 这 段 代 码 作 为回 答。
   事 实 上 解 决 这 个 问 题 的 方 法 并 不 十 分 复 杂, 我 们 只需 将 修

改 滚 动 条 位 置 的 时 间 稍 加 改 变 就 可 以 得 到 正 确 的结 果。 首 先
我 们 在 这 两 个 数 据 窗 口 中 各 声 明 一 个ue_scrollvertical 的 用 户 自

定 义 事 件 事 件。 传 递 一 个 参 数, 参 数 名 为vpos,integer 型, 通 过
传 值 法 传 递。 然 后 键 入 下 列 代 码:
   对dw_1 的SCROLLVERTICAL 事 件 编 程 如 下:
integer li_vmax_1, li_vpos_1,li_vmax_2, li_vpos_2
decimal ld_vmax_1_percent
li_vmax_1 = integer(dw_1.describe("datawindow.verticalscrollmaximum"))
li_vpos_1 = integer(dw_1.describe("datawindow.verticalscrollposition"))
li_vmax_2 = integer(dw_2.describe("datawindow.verticalscrollmaximum"))
ld_vmax_1_percent = li_vpos_1 / li_vmax_1
li_vpos_2 = ld_vmax_1_percent * li_vmax_2
if abs( li_vpos_2 - integer(dw_1.describe
("datawindow.verticalscrollposition")) ) > 1 then
//如dw_2应显示的位置与dw_2的当前位置不符,产生修改dw_2的事件
event post ue_scrollvertical( li_vpos_2 )
end if
对dw_1 的UE_SCROLLVERTICAL 事 件 编 程 如 下:
事 件: 自 定 义ue_scrollvertical
参 数:vpos integer 型
返 回 值:integer
string ls_ret_code
dw_2.modify("datawindow.verticalscrollposition="+string(vpos))
if ls_ret_code <> "" then
beep(6)
sle_1.text = "dw_1scroll = " + ls_ret_code + " vpos = " + string(vpo
s)
// 在scrollvertical 事 件 中 将 不 能 弹 出 错 误 信 息 框
end if
return 1
对dw_2 的SCROLLVERTICAL 事 件 编 程 如 下:
integer li_vmax_1, li_vpos_1,li_vmax_2, li_vpos_2
string ls_ret_code
decimal ld_vmax_2_percent
li_vmax_2 = integer(dw_2.describe("datawindow.verticalscrollmaximum"))
li_vpos_2 = integer(dw_2.describe("datawindow.verticalscrollposition"))
li_vmax_1 =integer(dw_1.describe("datawindow.verticalscrollmaximum"))
ld_vmax_2_percent = li_vpos_2 / li_vmax_2
li_vpos_1 = ld_vmax_2_percent * li_vmax_1
event post ue_scrollvertical(li_vpos_1)
//由于dw_1使用了retreive-as-needed,可能会自动将dw_2
滚回第一行,表现重新设置dw_2
ls_ret_code = dw_2.modify
("datawindow.verticalscrollposition="+string(li_vpos_2))
// 检 验 是 否 修 改 成 功
if ls_ret_code <> "" then
beep(6)
sle_1.text = "dw_2 mod" + ls_ret_code
end if
对dw_2 的UE_SCROLLVERTICAL 事 件 编 程 如 下:
事 件: 自 定 义ue_scrollvertical
参 数:vpos integer 型
返 回 值:integer
string ls_ret_code
ls_ret_code = dw_1.modify("datawindow.verticalscrollposition="+string(vpos))

// 检 验 是 否 修 改 成 功
if ls_ret_code <> ""then
beep(6)
sle_1.text = "dw_1 mod " + ls_ret_code
end if
   我 们 再 分 析 一 下 上 述 代 码 执 行 的 过 程: 用 户 点 击 了dw_1 的

滚 动 条, 使dw_1 将 滚 动 到 最 后 一 行, 产 生 了dw_1 的scrollvertical 事

件 一, 但 并 没 有 立 即 执 行, 只 放 在 了 事 件 队 列 的 后 面。系 统 首

先 发 现 数 据 窗 口 的Primary! 缓 冲 区 中 数 据 为 空, 向 后台 数 据 库
取 数 据, 并 使dw_2 复 位, 回 到 显 示 第 一 条 记 录 的位 置。 这 触 发 了

dw_2 的scrollvertical 事 件 二, 在 首 先 执 行 的 这个 事 件 二 中,PowerBu

ilder 根 据dw_2 当 前 显 示 的 是 第 一 条 记 录这 一 条 件, 产 生 一 个ue_

scrollvertical 事 件 三, 将dw_1 也 滚 回 显示 第 一 条 记 录, 但 是 这 个
事 件 三 并 没 有 立 即 触 发 执 行, 而是 放 在 了 事 件 队 列 的 最 后。 当

事 件 二 执 行 完 毕 后, 系 统 响应 用 户 对dw_1 进 行 的 向 下 翻 页 的 操

作, 并 触 发dw_1 事 件 一 的执 行。 这 时dw_1 显 示 的 是 用 户 希 望 看 到

的 正 确 的 记 录,PowerBuilder 根 据dw_1 的 当 前 位 置, 计 算 出dw_2 与
之 相 对 应 的 位 置, 将 修改dw_2 位 置 的 操 作ue_scrollvertical 事 件 四
放 在 了 事 件 队 列 的最 后。 这 时 该 执 行 事 件 三 了, 事 件 三 修 改dw

_1 滚 动 条 的 位置 至 第 一 条 记 录, 这 一 操 作 触 发 了dw_1 的scrollver

tical 事 件五, 此 时 两 个 数 据 窗 口 均 显 示 的 是 第 一 条 记 录。 在 这

一 事件 中,PowerBuilder 经 过 计 算, 得 到 了dw_2 应 显 示 的 位 置 与 当
前 位 置 相 等 的 结 论, 因 此 不 产 生ue_scrollvertical 事 件, 事 件五 没

有 对 系 统 产 生 任 何 影 响。 接 下 来 执 行 的 是 事 件 队 列中 仅 存 的
事 件 四, 在 这 个 事 件 里, 系 统 将dw_2 滚 动 至 正 确的 显 示 位 置 上
, 并 触 发 了dw_2 的scrollvertical 事 件 六。 在 事 件六 中, 系 统 又 产 生

dw_2 的ue_scrollvertical 事 件 七, 但 是 这 两 个事 件 均 没 有 对 显 示 造

成 任 何 影 响, 这 两 个 事 件 执 行 过 程中 也 没 有 再 产 生 新 的 事 件
, 这 一 系 列 的 响 应 便 最 终 结 束了。 而 最 终 的 结 果 是 两 个 数 据
窗 口 都 是 停 在 了 正 确 的 结果 上 了。
   同 理, 我 们 对 用 户 滚 动dw_2 后 系 统 的 响 应 进 行 细 致地 分 析,

也 可 以 看 到 上 述 代 码 的 正 确 性, 这 里 就 不 再 赘 述了。
   我 们 在 本 篇 中 编 写 的 代 码 可 能 并 不 一 定 在 您 开 发的 软 件
中 使 用 得 上, 但 是 如 果 您 能 够 对 这 一 代 码 执 行 的过 程 全 部 自
行 分 析 清 楚, 或 者 有 足 够 的 耐 性 看 明 白 了 上面 文 章 的 分 析, 那

么 您 对PowerBuilder 的 事 件 一 定 会 有 更 深的 理 解。
--
我想自由自在地飞......
飞过大海...
飞过沙漠...
飞翔在星的夜空......
※ 来源:.逸仙时空 Yat-sen Channel bbs.zsu.edu.cn.[FROM: 202.116.90.29]
----------------------------------------------------------------------------
----
[回到开始][上一层][下一篇]
欢迎访问Cterm主页

--
《列子·汤问》:“夸父不量力,欲追日影,逐之于隅谷之际。渴欲 得饮,赴饮河渭
。河渭不足,将走北饮大泽。未至,道渴而死。”

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.229.154]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.894毫秒