У меня есть unbound. Пользователь вводит некоторый действительный текст и оставляет элемент управления. Затем пользователь возвращается к элементу управления и вводит неверный текст. Я хочу показать пользователю сообщение, затем откат значения элемента управления до его предыдущего состояния и держать фокус в этом контроле.Альтернатива SendKeys «{Esc}» для несвязанного текстового поля Undo
Я попытался следующие подходы, ни один из которых получает меня именно то, что я ищу:
ВАРИАНТ A: SendKeys
Private Sub MyTextBox_BeforeUpdate(Cancel As Integer)
Cancel = DataIsInvalid(Me.MyTextBox.Value)
If Cancel Then SendKeys "{Esc}"
End Sub
Это именно то, что я хочу , но я действительно хочу избежать использования SendKeys
. Есть много проблем, которые приходят с использованием SendKeys: Vista+ compatibility, ключи отправляются в другое приложение, и т.д.
ВАРИАНТ 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
The Undo
здесь абсолютно ничего не делает. Но, по крайней мере, он не нарушает код 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 для этого поля, является превентивной ting {Название программы} для сохранения данных в поле.
ВАРИАНТ 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 запускается с до обрабатываются нажатия клавиш Enter или Enter или мыши.Поэтому, даже если мы попытаемся заставить фокус надлежащим образом контролировать (в соответствии с приведенным выше описанием .SetFocus
), программа немедленно переключит фокус на выбранный пользователем элемент управления.
Мне кажется, что «правильный» способ сделать это, чтобы использовать .Undo
метод контроля. Однако это не работает для несвязанных элементов управления. Это необъяснимый недостаток, особенно учитывая тот факт, что нажатие клавиши Escape выполняет эту функцию для несвязанного поля.
Есть ли лучший способ сделать это, или я должен просто придерживаться использования SendKeys
?
Автоматическое возвращение назад к предыдущему значению является палкой. Не могли бы вы оповестить пользователя, когда значение недействительно, сохраняя фокус в текстовом поле и позволяя пользователю выбирать между вводом нового допустимого значения или нажатием ESC для возврата к предыдущему значению? – HansUp
Вариант D определенно был бы моим выбором, но, к сожалению, ответ Microsoft на это касается Sendkeys по адресу: http://support.microsoft.com/kb/128195 – Newd
@HansUp: Это подход, который я обычно беру. В этом случае мне бы очень хотелось заставить предыдущее значение без вмешательства пользователя. – mwolfe02