Prevent Autoscrolling in RichTextBox

后端 未结 3 2056
萌比男神i
萌比男神i 2020-12-03 08:46

I have a readonly data logging window that I implemented using the RichTextBox control. I\'d like to be able to disable the autoscrolling that happens when the user clicks

3条回答
  •  眼角桃花
    2020-12-03 08:58

    The RichTextBox control automatically scrolls to the current selection, if the selection is not hidden. RichTextBox.AppendText(), in addition to appending text, also modifies the current selection, and so indirectly triggers the "autoscrolling" behaviour. Note that if RichTextBox.HideSelection is set to true, then the selection would be hidden when the control is not in focus; this explains the behaviour you described, where autoscrolling occurs only when the user clicks in the control. (thereby giving it focus) To prevent this, you need to do the following when appending text:

    1. Backup the initial selection
    2. Unfocus the control
    3. Hide selection (through a Windows message)
    4. AppendText
    5. Restore the initial selection
    6. Unhide selection
    7. Refocus the control

    You may also want to check whether the selection is already at the end of the text, and allow the autoscrolling behaviour if it is - this essentially emulates the behaviour of Visual Studio's Output window. For example:

        [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();
            }
        }
    

提交回复
热议问题