PowerBuilder 12.5:重置过滤器后无法保留选中行求助
问题解决方案
核心原因是重置过滤器/保存操作后,DataWindow会自动将焦点定位到第一行并触发rowfocuschanged事件,解决思路是「先保存当前行标识→执行操作→恢复焦点」,同时跳过不必要的事件逻辑。
1. 保存当前行的可靠标识
优先用主键值定位(比行号更可靠,因为过滤器重置后行号可能因缓冲区变化失效):
// 提前声明实例变量:string is_current_key is_current_key = dw_your.GetItemString(dw_your.GetRow(), "你的主键列名")
如果无主键,可临时保存主缓冲区行号(仅适用于操作前该行在主缓冲区的场景):
// 提前声明实例变量:long il_current_row il_current_row = dw_your.GetRow()
2. 跳过操作期间的焦点事件逻辑
添加实例变量boolean ib_skip_focus_event,在rowfocuschanged事件开头加判断:
// rowfocuschanged事件代码 if ib_skip_focus_event then return // 你的原有业务逻辑...
3. 重置过滤器并恢复焦点
ib_skip_focus_event = true // 执行重置过滤器操作 dw_your.SetFilter("") dw_your.Filter() // 定位回原选中行 if not isnull(is_current_key) and is_current_key <> "" then long ll_target_row ll_target_row = dw_your.Find("你的主键列名 = '" + is_current_key + "'", 1, dw_your.RowCount()) if ll_target_row > 0 then dw_your.ScrollToRow(ll_target_row) dw_your.SelectRow(0, false) dw_your.SelectRow(ll_target_row, true) end if else // 用行号恢复的分支 if il_current_row > 0 and il_current_row <= dw_your.RowCount() then dw_your.ScrollToRow(il_current_row) dw_your.SelectRow(0, false) dw_your.SelectRow(il_current_row, true) end if end if ib_skip_focus_event = false
4. 保存事务后恢复焦点
保存完成后(通常是Update()执行成功后),同样执行焦点恢复逻辑:
// 保存逻辑示例 if dw_your.Update() = 1 then commit using sqlca; ib_skip_focus_event = true // 如果保存后执行了Retrieve,也要先保存主键再执行该操作,然后恢复焦点 // dw_your.Retrieve() long ll_target_row ll_target_row = dw_your.Find("你的主键列名 = '" + is_current_key + "'", 1, dw_your.RowCount()) if ll_target_row > 0 then dw_your.ScrollToRow(ll_target_row) dw_your.SelectRow(0, false) dw_your.SelectRow(ll_target_row, true) end if ib_skip_focus_event = false else rollback using sqlca; end if
关键注意事项
- 主键定位是最稳妥的方式:重置过滤器时,过滤缓冲区的行会回到主缓冲区,行号会重新排序,依赖行号可能定位错误。
ScrollToRow要配合SelectRow使用:确保目标行不仅滚动到视图内,还保持选中状态。- 标志位
ib_skip_focus_event必须设置:避免重置过滤器时触发的rowfocuschanged事件因getrow()返回1而执行错误逻辑。
内容的提问来源于stack exchange,提问作者learning
相关产品推荐
相关产品推荐

