2015-05-08 72 views
11

Ho questo semplice Userform, dove ho solo TextBox1 e TextBox2. Inserisco del testo in entrambi. Supponiamo che lo stato attivo sia attivato (il cursore è posizionato su) TextBox2. Quando clicco su TextBox1, voglio che l'intero testo in questo controllo sia evidenziato (selezionato). Così io uso questo codice:Come selezionare il contenuto di una casella di testo dopo che è stato attivato?

Private Sub TextBox1_Enter() 
    With TextBox1 
     .SetFocus 
     .SelStart = 0 
     .SelLength = Len(.Text) 
    End With 
    MsgBox "enter event was fired" 
End Sub 

C'è un MsgBox al termine che viene caricato, questo significa che i lavori di evento. Tuttavia, il testo non è evidenziato. Come risolvere questo?

Io uso l'evento Enter e non vogliono utilizzare l'evento MouseDown, perché ho bisogno del codice di lavorare anche quando il TextBox1 viene attivato programatically, quindi mi sento l'evento Enter essere la scelta migliore, in quanto è sparato in entrambi i casi! Un altro svantaggio dell'evento MouseDown è: quando faccio clic per la seconda volta su TextBox1, non mi aspetto più che l'intero testo sia evidenziato, perché lo stato attivo è stato impostato sul primo clic e non è stato modificato dopo aver fatto clic sul stesso controllo per la seconda volta; quindi in questo caso vorrei che il cursore agisse normalmente (non per mantenere il testo segnato).

Aggiornamento
Quando scatto una volta sul TextBox1, mi aspetto di avere questo risultato: enter image description here
Se cliccato di nuovo, il momento clou sarebbe rimosso e il cursore potrebbe essere collocato nel luogo in cui è stato cliccato.

+0

Non sono riuscito a riprodurre il problema poiché il codice funzionava già per me, anche se utilizzato in modo programmatico! – R3uK

+1

Hai già una proprietà per questo denominato "EnterFieldBehavior'. Devi solo impostarlo su 'fmEnterFieldBehaviorSelectAll'. Questo è il valore predefinito per questa proprietà, quindi non devi fare nulla se non hai cambiato il valore della proprietà. Dovrebbe funzionare senza alcun bit di codice. –

+0

@ R3uK Non so perché, ma avere il codice sopra da solo non funziona per me - il testo non è selezionato al clic. Come [@vacip] (http://stackoverflow.com/users/4713729/vacip) ha detto, il motivo potrebbe essere che l'effettivo (nascosto) * click * si verifica dopo l'evento Enter e che annulla semplicemente la selezione. – ZygD

risposta

13

Non può essere più semplice di così ... Credo che

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 

Sia che si fa clic sulla casella di testo o scheda in esso, farà quello che vuoi. Per deselezionare il testo, utilizzare i tasti freccia.

Spiegazione

Se si esegue il debug del codice, vedrete che anche se avete detto .SetFocus, il focus non è sulla casella di testo. .SetFocus non funziona in TextBox1_Enter() ed è necessario che l'attivazione del resto del codice funzioni. E da qui la mia alternativa ...

alternativa

Potrebbe piacerti anche questa versione :) Questo supera il limite di usare il mouse nel controllo 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

Sembra che l'opzione alternativa funzioni brillantemente! Ho provato a fare una cosa molto simile con le variabili a livello di modulo, ma senza successo. Grazie per aver fatto luce! Ora lo lascerò così nella mia applicazione solo per assicurarmi che funzioni in ogni caso. – ZygD

+1

@Siddharth nice, +1 :-). – dee

+0

Enorme, grazie! PS: Una coincidenza - solo recentemente ho iniziato a lavorare con VB.NET (molto difficile al momento) e mi è capitato di atterrare su [il tuo blog] (https://siddharthrout.wordpress.com/vb-net-and-excel/) che è un grande aiuto :) Sei fantastico! :) – ZygD

-2

uso questo

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

Grazie, Vasily. Temo di non essere stato abbastanza chiaro. Ho aggiornato la domanda con uno screenshot del * "highlight" * che voglio raggiungere. – ZygD

5

Pff, mi ha portato un po '. In realtà, il tuo codice funziona, ma evidenzia il testo PRIMA che l'evento click si verifichi. Quindi facendo clic nella casella si sostituisce immediatamente la selezione creata dal codice. Ho usato una selezione ritardata, e funziona, anche se è un po 'disgustosa ...

Il codice per le caselle di testo:

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 

Nota che funziona anche senza esitare la {+ TimeValue (" 00:00:01 ")} parte, ma potrebbe teoricamente impedirgli di funzionare a volte. Hmm, a pensarci bene, basta lasciarlo fuori. Dubito che possa mai causare un problema.

Ora il codice di 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 

Spero che questo funziona anche per te. Problema inesteso :) Saluti!

+1

Grazie mille per la risposta. Funziona. Uso molto bello di 'Application.OnTime', e molto grazie per aver chiarito che l'effettivo * clic * accade prima che il testo sia evidenziato dal mio codice. Il codice funziona, tuttavia, aspetterò per diversi giorni, forse qualcun altro potrebbe fornire un'altra soluzione (come hai detto tu, questo non sembra molto bello, anche se mi piace molto). – ZygD

4

Non sono riuscito a selezionare/evidenziare il testo nell'evento Enter, poiché gli eventi mouse e mouse che seguono sono in qualche modo ripristinati.

Penso che il modo più corretto di realizzare ciò che si vuole è questo:

' 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 

Così ogni volta che si desidera attivare una della casella di testo a livello di codice, è necessario chiamare il sub SelectTboxText, che non è davvero fastidioso IMO. Ho fatto 2 pulsanti per questo come esempio.

+0

Bella soluzione. Anche se questo rende impossibile posizionare il cursore con il mouse, poiché seleziona sempre l'intero contenuto della casella di testo ogni volta che si fa clic all'interno di esso. ZygD ha detto: "Se fai clic di nuovo, il punto saliente verrà rimosso e il cursore verrà posizionato nel punto in cui è stato fatto clic." – vacip

+0

Lo hai provato? perché secondo me fa ciò che è stato richiesto e non ciò che pensi che farà. Il controllo sulla variabile 'LastEntered' è lì per questo, evidenzia solo il testo sul primo evento del mouse della stessa casella di testo –

+0

Spiacente, mio ​​male, ho completamente ignorato l'ultima parte inserita. Funziona ora. – vacip

-2

Il comportamento che si sta tentando di implementare è già incorporato nel TextBox. Quando si sposta il mouse sul lato sinistro della casella di testo, il puntatore del mouse punterà a destra. Se fai clic, selezionerà tutto il testo nel campo. Cliccando in qualsiasi altro punto si deselezionerà il testo.

Proverò alcune altre strategie per vedere se riesco a far funzionare tutto in una sub.

+1

Questo dovrebbe essere un commento e non una soluzione. Questo non risolve nulla –

+0

Grazie, Kris, per il commento. Questo utilizzo integrato non è molto conveniente, ecco perché cerco un'altra soluzione più intuitiva. – ZygD

1

Questo è in qualche modo un miglioramento della cosa ha postato @vacip. Il vantaggio che si ottiene è che non è necessario aggiungere un metodo separato nel modulo per ogni nuova casella di testo.

Il seguente codice nel tuo form utente:

'===== 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 

Il codice seguente va in un modulo:

'===== Module Code ======== 

Sub SelectAllText() 
    SendKeys "{HOME}+{END}", True 
End Sub 

Sub OnTextBoxEnter() 
    Application.OnTime Now + 0.00001, "SelectAllText", Now + 0.00002 
End Sub 
+0

Grazie. Potresti semplicemente spiegare quanto tempo è stato aggiunto con l'istruzione '+ 0.00001'? È in secondi, minuti o ore? – ZygD

+1

Aggiunge 1 secondo ed è funzionalmente uguale a 'TimeValue (" 00:00:01 ")'. La funzione 'OnTextBoxEnter' fa in modo che esegua' SelectAllText' dopo 1 secondo e attenda un altro 1 secondo prima di annullare l'operazione, nel caso in cui non venga eseguita per nessun motivo. –

-2

Prova lo stesso codice con TextBox1_MouseDown. Dovrebbe funzionare.

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

Sì, funziona, ma come ho detto nella domanda, 'MouseDown' da solo non mi aiuta, perché voglio anche essere in grado di chiamare facilmente la funzione a livello di programmazione. Finora, il problema sembra essere risolto, poiché ho implementato [questa soluzione] (http://stackoverflow.com/questions/30117252/how-to-select-the-contents-of-a-textbox-once-it -is-activated # 30178650) fornito da [Siddharth Rout] (http://stackoverflow.com/users/1140579/siddharth-rout) dopo aver spostato il suo codice fornito in 'MouseDown' in una funzione separata. – ZygD