PowerBuilder 19中按需屏蔽验证MessageBox弹窗的问题求助
PowerBuilder 19 新建按钮触发多次验证弹窗问题
在文章管理项目中,点击「新建」按钮会显示空的自由格式数据窗口dwc_article,用于录入文章详情(reference、name等字段)。我在dwc_article的ItemFocusChanged事件中添加了验证逻辑:当reference或name为空时弹出「Validation Error」消息框。
但存在以下问题:在表格格式数据窗口dwc_report中选中一行并点击「更新」按钮后,dwc_article会加载该文章详情;此时再点击「新建」按钮,会连续弹出3次验证错误消息框,需要在该场景下屏蔽这些弹窗。
相关脚本
dwc_article 的 ItemFocusChanged 事件脚本
integer li_row string ls_reference string ls_name li_row = This.GetRow() cb_3.Enabled = false cb_7.Enabled = false // Check if the focus is on the reference field if This.GetColumnName() <> "reference" then // Get the value of the reference field ls_reference = This.GetItemString(li_row, "reference") // Check if the reference field is empty or has more than 50 characters if IsNull(ls_reference) or Trim(ls_reference) = "" or Len(ls_reference) > 50 then MessageBox("Validation Error", "Reference field must not be empty and should have 50 characters or less.") // Set focus back to the reference field cb_3.Enabled = false cb_7.Enabled = false This.SetColumn("reference") return 1 // Prevent focus change else end if end if li_row = This.GetRow() // Check if the focus is on the name field if This.GetColumnName() <> "name" and This.GetColumnName() <> "reference" then // Get the value of the name field ls_name = This.GetItemString(li_row, "name") cb_3.Enabled = false cb_7.Enabled = false // Check if the name field is empty or has more than 50 characters if IsNull(ls_name) or Trim(ls_name) = "" or Len(ls_name) > 50 then MessageBox("Validation Error", "Name field must not be empty and should have 50 characters or less.") // Set focus back to the name field This.SetColumn("name") cb_3.Enabled = false cb_7.Enabled = false return 1 // Prevent focus change else cb_3.Enabled = true cb_7.Enabled = true end if end if return 0
「新建」按钮脚本
dwc_article.reset() dwc_article.insertrow(0) char reference dwc_article.scrolltorow(dwc_article.insertrow(0)) // Scroll to the newly inserted row long ll_new_row ll_new_row = dwc_article.InsertRow(0) dwc_article.ScrollToRow(ll_new_row) // Get the current date date ld_date_creation ld_date_creation = today() string ls_formatted_date ls_formatted_date = String(ld_date_creation, "yyyy-mm-dd") // Set the current date to the "date_de_creation" column dwc_article.SetItem(ll_new_row, "date_de_creation", ls_formatted_date) bl_btn_new_clicked = true dwc_article.modify("reference.Protect='0'") // This removes input capability from all columns dwc_article.modify("name.Protect='0'") dwc_article.modify("prix.Protect='0'") dwc_article.modify("date_de_creation.Protect='1'")
「更新」按钮脚本
long ll_row ll_row = dwc_report.GetSelectedRow(0) // Get the selected row index in dwc_report if ll_row >= 0 then // If a row is selected // Clear existing data in dwc_article dwc_article.Reset() long ll_nextRow ll_nextRow = dwc_article.RowCount() + 1 // Copy data from dwc_report to dwc_article dwc_report.RowsCopy(ll_row, ll_row, Primary!, dwc_article, ll_nextRow, Primary!) // Disable all inputs in dwc_article dwc_article.modify("reference.Protect='1'") dwc_article.modify("name.Protect='0'") dwc_article.modify("prix.Protect='0'") dwc_article.modify("date_de_creation.Protect='1'") // Retrieve data in dwc_article to reflect changes //dwc_report.retrieve() //dwc_article.retrieve() else MessageBox("No row selected", "Please select a row in the report") end if
问题根源与解决方案
问题根源
- 新建按钮重复插入行:当前「新建」按钮脚本中连续调用了3次
InsertRow(0),每次插入行都会触发ItemFocusChanged事件,导致验证逻辑被执行3次,对应弹出3次弹窗。 - 验证逻辑未区分手动操作与代码触发:当通过代码(如新建、更新)切换数据或行时,
ItemFocusChanged事件依然会执行验证,而此时用户还未开始手动输入,触发验证没有意义。
解决方案
步骤1:修复新建按钮的重复插入问题
删除重复的InsertRow调用,只保留一次插入操作,减少不必要的事件触发:
dwc_article.reset() // 只保留一次插入行操作 long ll_new_row ll_new_row = dwc_article.InsertRow(0) dwc_article.ScrollToRow(ll_new_row) // Get the current date date ld_date_creation ld_date_creation = today() string ls_formatted_date ls_formatted_date = String(ld_date_creation, "yyyy-mm-dd") // Set the current date to the "date_de_creation" column dwc_article.SetItem(ll_new_row, "date_de_creation", ls_formatted_date) bl_btn_new_clicked = true dwc_article.modify("reference.Protect='0'") dwc_article.modify("name.Protect='0'") dwc_article.modify("prix.Protect='0'") dwc_article.modify("date_de_creation.Protect='1'")
步骤2:添加全局标志位控制验证逻辑
在窗口的实例变量中添加一个布尔型变量ib_skip_validation,用于标记是否需要跳过验证:
// 窗口实例变量 boolean ib_skip_validation = false
然后修改「新建」和「更新」按钮脚本,在操作数据窗口前设置标志位为true,操作完成后恢复为false:
- 新建按钮脚本开头添加:
ib_skip_validation = true
结尾添加:
ib_skip_validation = false // 手动设置焦点到reference字段,避免自动触发验证 dwc_article.SetColumn("reference")
- 更新按钮脚本开头添加:
ib_skip_validation = true
结尾添加:
ib_skip_validation = false
步骤3:修改ItemFocusChanged事件的验证逻辑
在验证逻辑执行前先检查ib_skip_validation的值,若为true则直接跳过验证:
integer li_row string ls_reference string ls_name // 跳过代码触发的焦点变化验证 if ib_skip_validation then return 0 end if li_row = This.GetRow() cb_3.Enabled = false cb_7.Enabled = false // Check if the focus is on the reference field if This.GetColumnName() <> "reference" then // Get the value of the reference field ls_reference = This.GetItemString(li_row, "reference") // Check if the reference field is empty or has more than 50 characters if IsNull(ls_reference) or Trim(ls_reference) = "" or Len(ls_reference) > 50 then MessageBox("Validation Error", "Reference field must not be empty and should have 50 characters or less.") // Set focus back to the reference field cb_3.Enabled = false cb_7.Enabled = false This.SetColumn("reference") return 1 // Prevent focus change end if end if li_row = This.GetRow() // Check if the focus is on the name field if This.GetColumnName() <> "name" and This.GetColumnName() <> "reference" then // Get the value of the name field ls_name = This.GetItemString(li_row, "name") cb_3.Enabled = false cb_7.Enabled = false // Check if the name field is empty or has more than 50 characters if IsNull(ls_name) or Trim(ls_name) = "" or Len(ls_name) > 50 then MessageBox("Validation Error", "Name field must not be empty and should have 50 characters or less.") // Set focus back to the name field This.SetColumn("name") cb_3.Enabled = false cb_7.Enabled = false return 1 // Prevent focus change else cb_3.Enabled = true cb_7.Enabled = true end if end if return 0
额外优化建议
- 可以将验证逻辑移到
ItemChanged事件中,只在用户修改字段内容后触发验证,而非焦点变化时,这样更符合用户操作习惯。 - 避免在
ItemFocusChanged中强制设置焦点回退,除非是用户手动离开未填写的必填字段时再触发。
内容的提问来源于stack exchange,提问作者Hatem Moalla
相关产品推荐
相关产品推荐

