我有一个文本框的. multiline属性设置为true。每隔一段时间,我都会向它添加新的文本行。我希望文本框自动滚动到最底部的条目(最新的一个)每当添加一个新的行。我该怎么做呢?


当前回答

我用这个。简单、干净、快捷!

txtTCPTxRx.AppendText(newText);

下面是我使用的实际代码

ThreadSafe(() =>
      {
          string newLog = $"{DateTime.Now:HH:mm:ss:ffff->}{dLog}{Environment.NewLine}";
          txtTCPTxRx.AppendText(newLog);
      });

其他回答

每隔一段时间,我都会向它添加新的文本行。我希望文本框自动滚动到最底部的条目(最新的一个)每当添加一个新的行。

如果你使用文本框。AppendText(字符串文本),它将自动滚动到新追加的文本的末尾。如果在循环中调用它,它可以避免滚动条的闪烁。

它也恰好比连接到. text属性快一个数量级。尽管这可能取决于你调用它的频率;我在用一个紧循环测试。


如果它在文本框显示之前被调用,或者如果文本框不可见(例如在TabPanel的不同选项卡中),它将不会滚动。请参阅TextBox.AppendText()而不是自动滚动。这可能很重要,也可能不重要,这取决于当用户看不到文本框时是否需要自动滚动。

在这种情况下,其他答案的替代方法似乎也不管用。一种解决方法是在VisibleChanged事件上执行额外的滚动:

textBox.VisibleChanged += (sender, e) =>
{
    if (textBox.Visible)
    {
        textBox.SelectionStart = textBox.TextLength;
        textBox.ScrollToCaret();
    }
};

在内部,AppendText做了这样的事情:

textBox.Select(textBox.TextLength + 1, 0);
textBox.SelectedText = textToAppend;

但不应该有理由手动完成。

(如果你自己反编译它,你会发现它使用了一些可能更有效的内部方法,并且似乎有一个小的特殊情况。)

尝试将建议的代码添加到TextChanged事件:

private void textBox1_TextChanged(object sender, EventArgs e)
{
  textBox1.SelectionStart = textBox1.Text.Length;
  textBox1.ScrollToCaret();
}

当文本被更改时,这将滚动到文本框的末尾,但仍然允许用户向上滚动

outbox.SelectionStart = outbox.Text.Length;
outbox.ScrollToEnd();

在Visual Studio Enterprise 2017上测试

在。net 4.0中,接口似乎发生了变化。以下方法可以实现上述所有功能。正如Tommy Engebretsen所建议的,将其放在TextChanged事件处理程序中可以使其自动完成。

textBox1.ScrollToEnd();

关于皮特关于一个标签上的文本框的评论,我得到的工作方式是添加

textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();

到选项卡的Layout事件。