Autoscroll в нижней части многострочного текстового поля, обновляемого backgroundworker

У меня есть элемент управления рабочего стола, который настроен для выполнения задачи, и обновляет многострочное текстовое поле в моем основном пользовательском интерфейсе, используя процедуру делегирования. все это работает отлично, однако, как только обновление прокручивается в нижней части текстового поля, появятся полосы прокрутки, но непрерывное обновление заставляет текстовое поле оставаться заблокированным вверху. В идеале я бы хотел, чтобы текстовое поле автоматически прокручивалось вниз, чтобы показать последнюю запись в режиме реального времени. Какой был бы лучший способ реализовать это?

Я попытался использовать метод scrolltocaret(), с и без предшествующей ему команды SelectionStart = txtlog.Text.Length. возможно, я помещаю его в неправильное место?

некоторые примеры кода ниже:

Код делегирования:

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

Основная деятельность фонового работника:

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

Я предполагаю, что мой главный вопрос: я уверен, что textbox.scrolltocaret() - правильный метод для использования для того, что я хочу, но где это лучшее место для меня? Я пробовал это в делегате, главном фоном, а также до и после метода runworkerasync(). никто из них не работал, и теперь я в тупике!

Ответы

Ответ 1

Попробуйте так:

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

Код, который вы закомментировали, не был запущен в потоке графического интерфейса, и, как отметил М. Гранха, AppendText автоматически перейдет к добавленному тексту в поле, поэтому не нужно вызывать ScrollToCaret.

Ответ 2

xxx.SetFocus 'xxx = имя текстового поля

SendKeys "^ {END}" 'pop to last line