当前位置:  开发笔记 > 编程语言 > 正文

防止在RichTextBox中自动滚动

如何解决《防止在RichTextBox中自动滚动》经验,为你挑选了2个好方法。

我有一个readonly数据记录窗口,我使用RichTextBox控件实现.我希望能够禁用用户单击控件时发生的自动滚动,以便用户可以选择特定日志进行复制/粘贴操作或其他任何操作.但是,只要用户点击RichTextBox,它就会自动滚动到底部,这使得这很困难.

有人知道一种方法来覆盖这种行为吗?

谢谢!



1> SytS..:

如果未隐藏选择,RichTextBox控件将自动滚动到当前选择.RichTextBox.AppendText()除了附加文本外,还修改当前选择,因此间接触发"自动滚动"行为.请注意,如果RichTextBox.HideSelection设置为true,则当控件未处于焦点时,将隐藏选择; 这解释了您描述的行为,其中仅在用户单击控件时才会进行自动滚动.(从而给予关注)为防止这种情况,您需要在附加文本时执行以下操作:

    备份初始选择

    取消对焦控件

    隐藏选择(通过Windows消息)

    AppendText通过

    恢复初始选择

    取消隐藏选择

    重新聚焦控件

您可能还想检查选择是否已经在文本的末尾,并且如果是,则允许自动滚动行为 - 这实际上模拟了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();
        }
    }



2> itsmatt..:

你可以看看做这样的事情:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr LockWindowUpdate(IntPtr Handle);

然后在你的方法中附加日志数据(我在这里做了一些假设)你可能会做这样的事情:

LockWindowUpdate(this.Handle);
int pos = richTextBox1.SelectionStart;
int len = richTextBox1.SelectionLength;
richTextBox1.AppendText(yourText);
richTextBox1.SelectionStart = pos;
richTextBox1.SelectionLength = len;
LockWindowUpdate(IntPtr.Zero);

我做了一个带有计时器的测试应用程序,该计时器在richtextbox上执行了追加,并且它停止了滚动,因此我可以进行文本选择.它有一些位置问题,并不完美,但也许它会帮助你实现自己的解决方案.

祝一切顺利!

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有