C#如何防止RichTextBox滚动/跳转到顶部

3
似乎当使用一个时,你可以使用或向文本框中添加文本。 会滚动到底部,直接添加文本不会滚动,但当用户将文本框聚焦时,会跳转到顶部。
下面是我的函数:
// Function to add a line to the textbox that gets called each time I want to add something
// console = textbox
public void addLine(String line)
{
    // Invoking since this function gets accessed by another thread
    console.Invoke((MethodInvoker)delegate
    {
        // Check if user wants the textbox to scroll
        if (Settings.Default.enableScrolling)
        {
            // Only normal inserting into textbox here with AppendText()
        }
        else
        {
            // This is the part that doesn't work
            // When adding text directly like this the textbox will jump to the top if the textbox is focused, which is pretty annoying
            Console.WriteLine(line);
            console.Text += "\r\n" + line;
        }
    });
}

我还尝试了导入user32.dll并覆盖滚动函数,但效果不太好。

有人知道如何彻底停止文本框的滚动吗?

它不应该滚动到顶部,也不应该滚动到底部,当然也不应该滚动到当前选择位置,而是应该保持当前位置不变。

4个回答

5
 console.Text += "\r\n" + line;

那并不是你以为的那样。它是一个“赋值语句”,它会完全取代 Text 属性。+= 运算符是方便的语法糖,但实际执行的代码是:
 console.Text = console.Text + "\r\n" + line;

RichTextBox并不会尝试比较旧文本和新文本以查找可能保持插入符位置的匹配项。因此,它将插入符移回到文本的第一行。这反过来又导致滚动条回滚。请注意避免这种代码,它非常昂贵且不好用,如果你努力格式化文本,你将失去格式化。相反,应该使用AppendText()方法追加文本和SelectionText属性插入文本(在更改SelectionStart属性后)。这样做不仅速度快,而且没有滚动条。

1
我明白了,那么如何防止AppendText()滚动呢?AppendText()会让我再次滚动到底部。由于除了选择之外没有办法获取用户的当前位置,因此我无法回滚,除非在第一次滚动时就防止它滚动。 - user1137183
@user1137183:我看不出有什么问题。富文本框中的选择起点就是光标位置。在写入之前保存它,然后在恢复它? - Nyerguds

1

我需要实现类似的功能,所以想分享一下...

当:

  • 用户聚焦: 不滚动
  • 用户未聚焦: 滚动到底部

我采用了Hans Passant的建议,使用了AppendText()和SelectionStart属性。以下是我的代码:

int caretPosition = myTextBox.SelectionStart;

myTextBox.AppendText("The text being appended \r\n");

if (myTextBox.Focused)
{
    myTextBox.Select(caretPosition, 0);
    myTextBox.ScrollToCaret();
}

那个程序是可以运行的,但是由于某些问题,有时会出现跳跃的情况。 - Mattia

1

在此之后:

 Console.WriteLine(line);
 console.Text += "\r\n" + line;

只需添加这两行:

console.Select(console.Text.Length-1, 1);
console.ScrollToCaret();

愉快的编码


如果被聚焦,它将滚动到底部;如果没有被聚焦,它也会滚动到底部。 - user1137183

0

那么,如果我理解正确的话,你应该尝试这个:

Console.WriteLine(line);
console.SelectionProtected = true;
console.Text += "\r\n" + line;

当我尝试它时,它的工作方式就像你想要的那样。


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