web-dev-qa-db-fra.com

défilement automatique au bas de la zone de texte multiligne en cours de mise à jour par le backgroundworker

J'ai un contrôle de travailleur d'arrière-plan qui est configuré pour effectuer une tâche et mettre à jour une zone de texte multiligne sur mon interface utilisateur principale à l'aide d'une procédure de délégué. Tout cela fonctionne parfaitement. Cependant, lorsque la mise à jour défile au bas de la zone de texte, les barres de défilement apparaissent, mais l'actualisation continue entraîne le verrouillage de la zone de texte en haut. Idéalement, j'aimerais que la zone de texte se défile automatiquement jusqu'au bas pour afficher la dernière entrée en temps réel. Quel serait le meilleur moyen de mettre cela en œuvre?

J'ai essayé d'utiliser la méthode scrolltocaret(), avec et sans une commande SelectionStart = txtlog.Text.Length la précédant. peut-être que je le mets au mauvais endroit?

quelques exemples de code ci-dessous:

Code délégué:

Delegate Sub updateresults_delegate(ByVal textbox As TextBox, ByVal text As String)

Private Sub updatelog_threadsafe(ByVal textbox As TextBox, ByVal text As String)
            If textbox.InvokeRequired Then
                Dim mydelegate As New updateresults_delegate(AddressOf updatelog_threadsafe)
                Me.Invoke(mydelegate, New Object() {textbox, text})
                'Me.txtlog.SelectionStart = txtlog.Text.Length
                'Me.txtlog.ScrollToCaret()
            Else
                textbox.Text = text
            End If
        End Sub

activité principale des travailleurs de base:

For i As Integer = val1 To val2
'generate an IP address from split Host parts and current value of i
                Host = s1(0) & "." & s1(1) & "." & s1(2) & "." & i
                Try 'attempt to ping the IP
                    Dim reply As PingReply = pingsender.Send(Host, timeoutval, buffer, options)
                    If reply.Status = IPStatus.Success Then
                        name = System.Net.Dns.GetHostEntry(Host)'get DNS entry
                        resulttext += String.Format("{1} - {2}: reply: Bytes={3} time{4} TTL={5}{0}", vbCrLf, name.HostName, reply.Address.ToString, reply.Buffer.Length, getms(reply.RoundtripTime), reply.Options.Ttl) 'print out success text
                    Else
                        resulttext += String.Format("      {1}: Ping failed. {2}{0}", vbCrLf, Host, reply.Status.ToString) 'print out fail text
                    End If
                    updatelog_threadsafe(txtlog, resulttext) 'send text to textbox

            System.Threading.Thread.Sleep(1000)
        Catch ex As Exception

        End Try
    Next

Je suppose que ma question principale est la suivante: je suis presque certain que textbox.scrolltocaret() est la méthode correcte à utiliser pour ce que je veux, mais quel est le meilleur endroit pour le mettre? Je l'ai essayé dans le délégué, le backgroundworker principal, ainsi qu'avant et après la méthode runworkerasync(). rien de tout cela n'a fonctionné, et maintenant je suis perplexe!

15
almg

Essayez de cette façon:

'textbox.Text = text
textbox.AppendText(text)

Le code que vous avez commenté ne fonctionnait pas sur le fil de l'interface graphique et, comme M. Granja l'a fait remarquer, AppendText défilera automatiquement jusqu'au texte ajouté dans la zone. Il n'est donc pas nécessaire d'appeler ScrollToCaret.

23
LarsTech

xxx.SetFocus 'xxx = le nom de la zone de texte

SendKeys "^ {END}" 'pop jusqu'à la dernière ligne

0
peter