我有一个后台工作程序控件,用于执行任务,并使用委托过程更新主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()
方法之后。这些都没有奏效,现在我很难过!
答案 0 :(得分:24)
以这种方式尝试:
'textbox.Text = text
textbox.AppendText(text)
您注释掉的代码没有在GUI线程上运行,正如M Granja所指出的,AppendText将自动滚动到框中的附加文本,因此无需调用ScrollToCaret。
答案 1 :(得分:0)
xxx.SetFocus' xxx =文本框的名称
SendKeys" ^ {END}" '弹出到最后一行