多行文本框被后台工作者更新时自动滚动到底部

17

我有一个后台工作控件,设置为执行任务并使用委托过程更新我的主UI中的多行文本框。这一切都工作得非常完美,但是一旦更新内容超出文本框底部,滚动条会出现,但持续刷新会导致文本框锁定在顶部。理想情况下,我希望文本框能够自动滚动到底部,以实时显示最新条目。最佳实现方式是什么?

我已经尝试使用 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()方法之前和之后,但这些都没有起作用,现在我感到困惑!

2个回答

26

试着这样做:

'textbox.Text = text
textbox.AppendText(text)
你注释掉的那段代码没有运行在GUI线程上,正如M Granja所指出的,AppendText会自动滚动到在框中添加的文本,因此不需要调用ScrollToCaret。

感谢您的回复。我已将此添加到委托中的IF语句中,现在它可以正常工作了!最初,每次刷新都会导致一个有趣的复合消息(1个结果,然后2个结果,然后3个结果等)。这是因为我在发送到文本框的字符串上使用了+=。现在已经修复了。谢谢! - almg
2
仅供参考,来自这个答案:如果您使用TextBox.AppendText(string text),它将自动滚动到新附加文本的末尾。如果您在循环中调用它,它可以避免闪烁的滚动条。 它还比连接到.Text属性上快一个数量级。虽然这可能取决于您调用它的频率; - M Granja

0

xxx.SetFocus ' xxx代表文本框的名称

SendKeys "^{END}" ' 跳转到最后一行


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接