自动滚动到由 backgroundworker 更新的多行文本框的底部
Posted
技术标签:
【中文标题】自动滚动到由 backgroundworker 更新的多行文本框的底部【英文标题】:autoscroll to bottom of multiline textbox being updated by backgroundworker 【发布时间】:2013-11-12 18:16:31 【问题描述】:我有一个后台工作控件,它设置为执行任务,并使用委托过程更新我的主 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 time4 TTL=50", 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. 20", 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】:xxx.SetFocus ' xxx = 文本框的名称
SendKeys "^END" ' 弹出到最后一行
【讨论】:
【参考方案2】:试试这个方法:
'textbox.Text = text
textbox.AppendText(text)
您注释掉的代码没有在 GUI 线程上运行,正如 M Granja 指出的那样,AppendText 会自动滚动到框中的附加文本,因此无需调用 ScrollToCaret。
【讨论】:
感谢您的回复。我已将此添加到委托中的 IF 语句中,现在这很有效!最初,每次刷新都会导致一条有趣的复合消息(1 个结果,然后是 2 个结果,然后是 3 个结果,等等)。这原来是因为 += 我在被发送到文本框的字符串上。现在已解决。谢谢! 请注意,来自this answer :如果您使用TextBox.AppendText(string text),它将自动滚动到新附加文本的末尾。如果您在循环中调用它,它可以避免闪烁的滚动条。它也恰好比连接到 .Text 属性快一个数量级。虽然这可能取决于您调用它的频率;以上是关于自动滚动到由 backgroundworker 更新的多行文本框的底部的主要内容,如果未能解决你的问题,请参考以下文章
如何在WinForms中制作自动滚动多行TextBox? [重复]
BackgroundWorker:Argument-Object 的子代