禁用RichTextBox自动滚动功能

5

我正在使用RichTextBox控件来显示应用程序日志。我每秒更新一次控件,并调用几次RichTextBox :: AppendText方法。对我来说真正烦人的是光标不断滚动到文本的最后一行。当用户需要分析在开头的日志时,这是非常不舒服的。我尝试了以下解决方案来解决我的问题:

int pos = tb_logs.SelectionStart;
tb_logs.AppendText("log message");
tb_logs.SelectionStart = pos;

这并没有解决问题的核心,因为控件正在定期重新绘制,这非常分散注意力。有更简洁的解决方案吗?


这听起来有点奇怪,因为到达结尾应该在某个地方明确地完成。你确定追加代码不会将选择设置为结尾吗? - Felice Pollano
不,只需使用AppendText("text")、AppendText("\t")和AppendText("\n")。 - truthseeker
我发现了一件有趣的事情。只有在文本区域获得焦点时,自动滚动才会发生。在点击文本区域后,事情就出了问题。如果我不点击它,我可以同时使用滚动条滚动消息和添加新消息,而文本不会跳动。 - truthseeker
请参考在C# RichTextBox中防止自动滚动,该链接描述了相同的问题。 - SytS
2个回答

7
如果您的问题是在添加日志文本时,“垂直滚动条”向下滚动,但您希望它始终在顶部: 您需要为VScroll、TextChanged事件添加事件处理程序,在事件处理程序中将滚动设置为顶部。
richTextBox1.VScroll += HandleRichTextBoxAdjustScroll;
richTextBox1.TextChanged += HandleRichTextBoxAdjustScroll;

private const UInt32 SB_TOP = 0x6;
private const UInt32 WM_VSCROLL = 0x115;

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(IntPtr hWnd, UInt32 Msg,
    IntPtr wParam, IntPtr lParam);

private void HandleRichTextBoxAdjustScroll(Object sender,
    EventArgs e)
{
    PostMessage(handle, WM_VSCROLL, (IntPtr)SB_TOP, IntPtr.Zero);
}

您也可以使用水平滚动条完成相同的操作。将 WM_VSCROLL 替换为 WM_HSCROLL,将 SB_TOP 替换为 SB_LEFT。

private const UInt32 WM_HSCROLL = 0x0114;
private const UInt32 SB_LEFT = 0x06;

0

你可以尝试使用tb_logs.SelectionLength = 1; 和 SelectionStart。这会从你的当前位置开始选中一个字符。

虽然我没有试过,但是可能有效。


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