我有一个未绑定的文本框控件。用户输入一些有效的文本并离开该控件。然后,用户返回到该控件并输入一些无效的文本。我想向用户显示一条消息,然后将控件的值回滚到其先前的状态,并保持焦点在该控件中。
我尝试了以下方法,但没有一个能完全符合我的要求:
选项A:SendKeys
这里的“撤销”操作实际上没有任何作用,但至少它不会破坏BeforeUpdate事件中的Cancel=True代码并允许无效数据存在。
选项D:在BeforeUpdate事件中显式还原旧值。
尝试将以前的值分配给文本框的
选项E:在AfterUpdate事件中显式恢复旧值。
这非常接近期望的行为。 不幸的是,由于AfterUpdate事件在处理Tab / Enter键按下或鼠标单击事件之前运行,因此无法保持对控件的焦点。 因此,即使我们尝试通过上面的.SetFocus语句强制将焦点放在正确的控件上,程序也会立即将焦点转移到用户选择的控件。
在我看来,做到这一点的“正确”方法是使用控件的.Undo方法。 但是,对于未绑定的控件,这种方法不起作用。 这是一个难以理解的缺陷,特别是考虑到Escape键按下可以为未绑定字段执行此功能。
是否有更好的方法来做到这一点,还是我应该坚持使用SendKeys?
我尝试了以下方法,但没有一个能完全符合我的要求:
选项A:SendKeys
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
Cancel = DataIsInvalid(Me.MyTextBox.Value)
If Cancel Then SendKeys "{Esc}"
End Sub
这正是我想要的,但我真的想避免使用SendKeys
。使用SendKeys会带来许多问题:Vista+兼容性,键被发送到不同的应用程序等。
选项B:控件的撤销方法
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
Cancel = DataIsInvalid(Me.MyTextBox.Value)
If Cancel Then Me.MyTextBox.Undo
End Sub
对于未绑定控件来说,这种方法根本不起作用(至少在MS Access 2002/XP上是如此)。该方法无法将MyTextBox的值恢复为有效输入。但是,它允许用户将焦点更改到新控件,同时保留Me.MyTextBox中的无效输入!难以置信!!!
选项C:表单的撤消方法
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
Cancel = DataIsInvalid(Me.MyTextBox.Value)
If Cancel Then Me.Form.Undo
End Sub
这里的“撤销”操作实际上没有任何作用,但至少它不会破坏BeforeUpdate事件中的Cancel=True代码并允许无效数据存在。
选项D:在BeforeUpdate事件中显式还原旧值。
Private mPrevMyTextBoxValue As Variant
Private Sub MyTextBox_AfterUpdate()
mPrevMyTextBoxValue = Me.MyTextBox.Value
End Sub
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
Cancel = DataIsInvalid(Me.MyTextBox.Value)
If Cancel Then Me.MyTextBox.Value = mPrevMyTextBoxValue
'If Cancel Then Me.MyTextBox.Text = mPrevMyTextBoxValue
End Sub
尝试将以前的值分配给文本框的
.Value
或.Text
属性均会导致相同的错误消息:
为该字段设置的BeforeUpdate或ValidationRule属性的宏或函数正在阻止{Program Name}保存字段中的数据。
选项E:在AfterUpdate事件中显式恢复旧值。
Private mPrevMyTextBoxValue As Variant
Private Sub MyTextBox_AfterUpdate()
If DataIsInvalid(Me.MyTextBox.Value) Then
Me.MyTextBox.Value = mPrevMyTextBoxValue
Me.MyTextBox.SetFocus
Else
mPrevMyTextBoxValue = Me.MyTextBox.Value
End If
End Sub
这非常接近期望的行为。 不幸的是,由于AfterUpdate事件在处理Tab / Enter键按下或鼠标单击事件之前运行,因此无法保持对控件的焦点。 因此,即使我们尝试通过上面的.SetFocus语句强制将焦点放在正确的控件上,程序也会立即将焦点转移到用户选择的控件。
在我看来,做到这一点的“正确”方法是使用控件的.Undo方法。 但是,对于未绑定的控件,这种方法不起作用。 这是一个难以理解的缺陷,特别是考虑到Escape键按下可以为未绑定字段执行此功能。
是否有更好的方法来做到这一点,还是我应该坚持使用SendKeys?