Как выбрать содержимое текстового поля после его активации?
У меня есть эта простая Userform, где у меня есть только TextBox1
и TextBox2
. Я ввожу в них текст. Предположим, что фокус включен (курсор находится) TextBox2
. Когда я нажимаю TextBox1
, я хочу, чтобы весь текст в этом элементе управления был выделен (выбран). Таким образом, я использую этот код:
Private Sub TextBox1_Enter()
With TextBox1
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
End With
MsgBox "enter event was fired"
End Sub
В конце загружается MsgBox
, что означает, что событие работает. Однако текст не подсвечивается. Как это исправить?
Я использую событие Enter
и не хочу использовать событие MouseDown
, потому что мне нужен код, который также работает, когда TextBox1
активируется программно, поэтому я чувствую, что событие Enter
лучший выбор, поскольку он выстрелил в обоих случаях! Еще один недостаток события MouseDown
: когда я нажимаю второй раз на TextBox1
, я бы не ожидал, что весь текст будет выделен больше, потому что фокус был установлен на первый клик, и он не был изменен после Во второй раз я нажал на один и тот же элемент управления; поэтому в этом случае я бы хотел, чтобы курсор работал нормально (не для того, чтобы текст был помечен).
Обновление
Когда я нажимаю один раз на TextBox1
, я ожидаю получить этот результат:
![enter image description here]()
Если щелкнуть снова, подсветка будет удалена, и курсор будет помещен в то место, где он был нажат.
Ответы
Ответ 1
Не может быть проще, чем это, я думаю...
Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
With TextBox1
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
Если вы нажмете на текстовое поле или вкладку в него, он будет делать то, что вы хотите. Чтобы отменить выбор текста, используйте клавиши со стрелками.
Объяснение
Если вы отлаживаете код, вы увидите, что даже если вы сказали .SetFocus
, фокус не находится в текстовом поле. .SetFocus
не работает в TextBox1_Enter()
, и вам нужно сосредоточиться на остальной части кода для работы. И, следовательно, моя альтернатива...
Alternative
Вам также может понравиться эта версия:) Это преодолевает ограничение использования мыши в TextBox
Dim boolEnter As Boolean
Private Sub TextBox1_Enter()
boolEnter = True
End Sub
Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
If boolEnter = True Then
With TextBox1
.SelStart = 0
.SelLength = Len(.Text)
End With
boolEnter = False
End If
End Sub
Ответ 2
Pff, взял меня. На самом деле, ваш код работает, но он выделяет текст до того, как произойдет событие клика. Таким образом, вы щелкаете в ящике, мгновенно переопределяя выбор, созданный кодом.
Я использовал отложенный выбор, и он работает, хотя это немного отвратительно...
Код для текстовых полей:
Private Sub TextBox1_Enter()
Application.OnTime Now + TimeValue("00:00:01"), "module1.SelectText1"
End Sub
Private Sub TextBox2_Enter()
Application.OnTime Now, "module1.SelectText2"
End Sub
Обратите внимание, что он работает даже с частью {+ TimeValue ( "00:00:01" )}, но это теоретически может помешать ему работать время от времени. Хм, подумав, просто оставьте это. Я сомневаюсь, что это когда-нибудь вызовет проблему.
Теперь код в модуле 1:
Sub SelectText1()
UserForm1.TextBox1.SelStart = 0
UserForm1.TextBox1.SelLength = Len(UserForm1.TextBox1.Text)
End Sub
Sub SelectText2()
UserForm1.TextBox2.SelStart = 0
UserForm1.TextBox2.SelLength = Len(UserForm1.TextBox2.Text)
End Sub
Надеюсь, это сработает и для вас. Инертная проблема.:) Приветствия!
Ответ 3
Мне не удавалось выбрать/выделить текст в событии Enter, поскольку события mousedown и mouseup, следующие после этого, несколько сбрасывают выбор.
Я думаю, что самый правильный способ добиться того, чего вы хотите, это:
' if you want to allow highlight more then once, reset the variable LastEntered prior to call SelectTboxText:
' LastEntered = ""
' SelectTboxText TextBox2
Dim LastEntered As String
' Button to select Textbox1
Private Sub CommandButton1_Click()
SelectTboxText TextBox1
End Sub
' Button to select Textbox2
Private Sub CommandButton2_Click()
SelectTboxText TextBox2
End Sub
Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
SelectTboxText TextBox1
End Sub
Private Sub TextBox2_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
SelectTboxText TextBox2
End Sub
Public Sub SelectTboxText(ByRef tBox As MSForms.TextBox)
If LastEntered <> tBox.Name Then
LastEntered = tBox.Name
With tBox
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
End With
End If
End Sub
Итак, каждый раз, когда вы хотите программно использовать один из текстовых полей, вы должны вызвать sub SelectTboxText, что на самом деле не раздражает IMO. В качестве примера я сделал 2 кнопки.
Ответ 4
Это несколько улучшает то, что опубликовано @vacip. Вы получаете то, что вам не нужно добавлять отдельный модуль в модуль для каждого нового текстового поля.
Следующий код в пользовательской форме:
'===== User Form Code ========
Option Explicit
Private Sub TextBox1_Enter()
OnTextBoxEnter
End Sub
Private Sub TextBox2_Enter()
OnTextBoxEnter
End Sub
Private Sub TextBox3_Enter()
OnTextBoxEnter
End Sub
В модуле содержится следующий код:
'===== Module Code ========
Sub SelectAllText()
SendKeys "{HOME}+{END}", True
End Sub
Sub OnTextBoxEnter()
Application.OnTime Now + 0.00001, "SelectAllText", Now + 0.00002
End Sub
Ответ 5
Я знаю, что это сильно устарело, но я оставляю это здесь на случай, если это поможет кому-то на моем месте.
Что я хочу это:
- Если я нажму на поле в первый раз: выделите весь текст
- Если я нажму на нее в следующий раз: поместите курсор туда, где находится мышь, и позвольте мне использовать мышь для выбора подстроки
Во-первых, важно знать, что "Выделение всего текста" является поведением по умолчанию при вставке в TextBox, и что "Поместить курсор здесь" является поведением по умолчанию при нажатии на TextBox, поэтому нам нужно беспокоиться только о том, что такое мышь делает.
Для этого мы можем отслеживать активный элемент управления, но только тогда, когда мышь перемещается над нашим TextBox (т.е. Перед щелчком)
Код:
Private m_ActiveControlName As String
Private Sub Text1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
m_ActiveControlName = Me.ActiveControl.Name
End Sub
Private Sub Text1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If m_ActiveControlName <> Me.Text1.Name Then
Call Text1_Enter 'we don't have to use Text1_Enter for this, any method will do
Exit Sub 'quit here so that VBA doesn't finish doing its default Click behaviour
End If
End Sub
Private Sub Text1_Enter()
With Text1
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
Ответ 6
Private Sub UserForm_Initialize()
TextBox1.SetFocus
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1.Text)
End Sub
Добавьте это к коду формы
Ответ 7
используйте этот
Private Sub TextBox1_Enter()
With TextBox2
.ForeColor = vbBlack
.Font.Bold = False
End With
With TextBox1
.ForeColor = vbRed
.Font.Bold = True
End With
End Sub
Private Sub TextBox2_Enter()
With TextBox1
.ForeColor = vbBlack
.Font.Bold = False
End With
With TextBox2
.ForeColor = vbRed
.Font.Bold = True
End With
End Sub
Ответ 8
Поведение, которое вы пытаетесь реализовать, уже встроено в TextBox
. Когда вы перемещаете мышь над левой стороной текстового поля, указатель мыши укажет вправо. Если вы нажмете, он выберет весь текст в поле. Щелчок в другом месте отменяет выбор текста.
Я попробую еще несколько стратегий, чтобы увидеть, могу ли я заставить это работать в одном Sub.
Ответ 9
Попробуйте использовать тот же код с TextBox1_MouseDown
. Он должен работать.
Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
With TextBox1
.SetFocus
.SelStart = 0
.SelLength = Len(.Text)
End With
MsgBox "Text in TextBox1 is selected"
End Sub