我有一个使用 RichTextBox 控件实现的只读数据记录窗口。我希望能够禁用用户单击控件时发生的自动滚动,以便用户可以选择特定日志进行复制/粘贴操作或其他操作。然而,一旦用户单击 RichTextBox,它就会自动滚动到底部,这使得这变得很困难。
有人知道一种方法来覆盖这种行为吗?
Thanks!
如果未隐藏所选内容,RichTextBox 控件会自动滚动到当前所选内容。 RichTextBox.AppendText() 除了附加文本之外,还修改当前选择,因此间接触发“自动滚动”行为。请注意,如果 RichTextBox.HideSelection 设置为 true,则当控件未处于焦点时,所选内容将被隐藏;这解释了您所描述的行为,其中仅当用户单击控件时才会发生自动滚动。 (从而给予它焦点)
为了防止这种情况,您需要在附加文本时执行以下操作:
- 备份初始选择
- 取消控制焦点
- 隐藏选择(通过 Windows 消息)
- 附加文本
- 恢复初始选择
- 取消隐藏选择
- 重新调整控制焦点
您可能还想检查所选内容是否已位于文本末尾,如果是,则允许自动滚动行为 - 这实质上模拟了 Visual Studio 输出窗口的行为。例如:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
const int WM_USER = 0x400;
const int EM_HIDESELECTION = WM_USER + 63;
void OnAppend(string text)
{
bool focused = richTextBox1.Focused;
//backup initial selection
int selection = richTextBox1.SelectionStart;
int length = richTextBox1.SelectionLength;
//allow autoscroll if selection is at end of text
bool autoscroll = (selection==richTextBox1.Text.Length);
if (!autoscroll)
{
//shift focus from RichTextBox to some other control
if (focused) textBox1.Focus();
//hide selection
SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 1, 0);
}
richTextBox1.AppendText(text);
if (!autoscroll)
{
//restore initial selection
richTextBox1.SelectionStart = selection;
richTextBox1.SelectionLength = length;
//unhide selection
SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 0, 0);
//restore focus to RichTextBox
if(focused) richTextBox1.Focus();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)