2015-05-08 2 views
11

У меня есть эта простая 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, я бы не ожидал, что весь текст будет выделен больше, потому что фокус был установлен на первом клике, и он не изменился после того, как я нажал на тот же контроль во второй раз; поэтому в этом случае я бы хотел, чтобы курсор работал нормально (чтобы не помечать текст).

Update
Когда я один раз нажать на TextBox1, я ожидаю получить этот результат: enter image description here
Если нажата снова, подсветка будет удалена, и курсор будет помещен в том месте, где это было щелкнул.

+0

Мне не удалось воспроизвести вашу проблему, поскольку ваш код уже работал на меня, даже если он используется программно! – R3uK

+1

У вас уже есть свойство для этого имени 'EnterFieldBehavior'. Вам просто нужно установить его в 'fmEnterFieldBehaviorSelectAll'. Это значение по умолчанию для этого свойства, поэтому вам не нужно ничего делать, если вы не изменили значение свойства. Он должен работать без какого-либо кода. –

+0

@ R3uK Я не знаю, почему, но наличие вышеописанного кода для меня не работает - текст не выбран по щелчку. Как сказал [@vacip] (http://stackoverflow.com/users/4713729/vacip), причиной может быть то, что фактическое (скрытое) событие * click * происходит после события Enter, и это просто отменяет выбор. – ZygD

ответ

13

не может быть более простым, чем это я думаю ...

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, акцент делается не на TextBox. .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 
+1

Кажется, что альтернативный вариант работает блестяще! Я попытался сделать очень похожую вещь с переменными на уровне модуля, но безуспешно. Спасибо, что пролил свет! Теперь я просто оставлю это в своем приложении, чтобы убедиться, что он работает в каждом случае. – ZygD

+1

@ Сиддхарт хороший, +1 :-). – dee

+0

Огромное спасибо! PS: Совпадение - совсем недавно я начал работать с VB.NET (на данный момент очень сложно), и мне довелось приземлиться на [ваш блог] (https://siddharthrout.wordpress.com/vb-net-and-excel/), который является огромной помощью :) Ты потрясающий! :) – ZygD

-2

использование этого

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 
+0

Спасибо, Василий. Боюсь, я не был достаточно ясен. Я обновил вопрос с помощью скриншота * «highlight» *, который я хочу достичь. – ZygD

5

Пфф, мне потребовалось некоторое время. На самом деле, ваш код работает, но он выделяет текст до того, как произойдет событие клика. Таким образом, вы щелкаете в ящике, мгновенно переопределяя выбор, созданный кодом. я использовал задержанный выбор, и он работает, хотя это немного противно ...

Код для текстовых полей:

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 

Обратите внимание, что он работает даже withouth в {+ TimeValue (» 00:00:01 ")}, но это теоретически может помешать ему работать время от времени. Хм, подумав, просто оставьте это. Я сомневаюсь, что это вызовет проблему.

Теперь код в Module1:

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 

Надеется, что это работает для вас тоже. Инертная проблема. :) Приветствия!

+1

Очень спасибо за ответ. Оно работает. Действительно приятное использование 'Application.OnTime' и очень спасибо за разъяснение, что фактический * щелчок * происходит до того, как текст будет выделен моим кодом. Однако код работает, я буду ждать несколько дней, может быть, кто-то другой может предоставить другое решение (как вы сказали, это выглядит не очень красиво, хотя мне это очень нравится). – ZygD

4

Мне не удалось выделить/выделить текст в событии 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 

Таким образом, каждый раз, когда вы хотите, чтобы активировать один из текстового поля в программе, вы должны вызвать суб SelectTboxText, который не является действительно раздражает ИМО. В качестве примера я сделал 2 кнопки.

+0

Хорошее решение. Хотя это делает невозможным размещение курсора мышью, поскольку он всегда выбирает все содержимое текстового поля всякий раз, когда вы нажимаете на него. ZygD сказал: «Если щелкнуть снова, подсветка будет удалена, и курсор будет помещен в то место, где он был нажат». – vacip

+0

Вы протестировали его? потому что, согласно мне, он делает то, что требуется, а не то, что, по вашему мнению, будет делать. Проверка на переменную 'LastEntered' есть для этого, она только выделяет текст в FIRST mouse event того же текстового поля –

+0

Извините, мой плохой, я полностью пропустил последнюю введенную часть. Сейчас это работает. – vacip

-2

Поведение, которое вы пытаетесь реализовать, уже встроено в TextBox. Когда вы перемещаете мышь над левой стороной текстового поля, указатель мыши укажет вправо. Если вы нажмете, он выберет весь текст в поле. Щелчок в другом месте отменяет выбор текста.

Я попробую еще несколько стратегий, чтобы увидеть, могу ли я заставить это работать в одном Sub.

+1

Это должен быть комментарий, а не решение. Это ничего не решит –

+0

Спасибо, Крис, за комментарий. Это встроенное использование не очень удобно, поэтому я ищу другое, более интуитивно понятное решение. – ZygD

1

Это несколько улучшенный вариант что @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 
+0

Спасибо. Не могли бы вы объяснить, сколько времени добавлено с помощью '+ 0.00001'? Это в секундах, минутах или часах? – ZygD

+1

Он добавляет 1 секунду и функционально такой же, как 'TimeValue (« 00:00:01 »)'. Функция «OnTextBoxEnter» заставляет его выполнять «SelectAllText» через 1 секунду и ждать еще 1 секунду, прежде чем отменяет операцию, если она не будет выполнена по какой-либо причине. –

-2

Попробуйте тот же код с 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 
+1

Да, это работает, но, как я сказал в вопросе, «MouseDown» сам по себе не помогает, потому что я также хочу иметь возможность легко вызвать функцию программно. Пока проблема решена, поскольку я реализовал [это решение] (http://stackoverflow.com/questions/30117252/how-to-select-the-contents-of-a-textbox-once-it -is-activated # 30178650), предоставленный [Siddharth Rout] (http://stackoverflow.com/users/1140579/siddharth-rout) после перемещения его кода, предоставленного в 'MouseDown', в отдельную функцию. – ZygD

Смежные вопросы