none
C# RichTextBox jumps to bottom after RichTextBox.TextAlignment changed. RRS feed

  • Question

  • I'm writing a C# WinForms app using a RichTextBox. When I open an .rtf file that contains text and images and try to change any selected image or text's alignment to HorizontalAlignment.Left, HorizontalAlignment.Center or HorizontalAlignment.Right, the RichTextFile performs the operation correctly, but then the cursor jumps down to the bottom of the RichtTextBox. Here's the code for the SelectionAlignment ops...

     private void TsbtnAlignLeft_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in spltMain.Panel2.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Left;
                }
            }
    
            private void TsbtnAlignCenter_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in spltMain.Panel2.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Center;
                }
            }
    
            private void TsbtnAlignRight_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in spltMain.Panel2.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Right;
                }
            }

    The problem occurs whether I'm working with a block of text or an image and it only happens with .rtf file I open, rather than new .rtf files I create. I want the RichTextBox to stay exactly where it is. How can I prevent the jump to the bottom? Could it be something in the .rtf file's formatting (UTF8, Unicode, ANSI) that's causing this?




    • Edited by Milwaukee Broad Friday, September 6, 2019 8:21 PM More info
    • Moved by CoolDadTx Monday, September 9, 2019 2:00 PM Winforms related
    Friday, September 6, 2019 7:30 PM

All replies

  • Hi Milwaukee Broad, 

    Thank you for posting here.

    According to your description, I make a test on my side.

    I use a RichTextBox which in a panel to load a .rtf file, but there is no cursor in RichTextBox after I click the Button.

    Here’s my code.

            private void Button1_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Left;
                }
            }
    
            private void Button2_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Center;
                }
            }
    
            private void Button3_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Right;
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                OpenFileDialog openFile1 = new OpenFileDialog();
    
                openFile1.DefaultExt = "*.rtf";
                openFile1.Filter = "RTF Files|*.rtf";
    
                if (openFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
                   openFile1.FileName.Length > 0)
                {
                    richTextBox1.LoadFile(openFile1.FileName);
                }
            }

    Result of the test:

    Could you provide more information for us to reproduce your problem? It will help us to analyze your problem.

    We are waiting for your update.

    Best Regards,

    Xingyu Zhao



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, September 9, 2019 6:28 AM
  • Thanks for your reply, Xingyu Zhao. Here's my code for opening an .rtf file, which includes creating a RichTextBox dynamically...

    private void MnuOpenDocument_Click(object sender, EventArgs e)
            {
                using (OpenFileDialog ofd = new OpenFileDialog())
                {
                    ofd.Multiselect = false;
                    ofd.Title = "Open...";
                    ofd.Filter = "Rich Text Files (.rtf)|*.rtf";
                    if (DialogResult.OK == ofd.ShowDialog())
                    { 
                        bool bl = false;
                        foreach (Control ctrl in spltMain.Panel2.Controls)
                        {
                            if (ctrl is RichTextBox)
                                bl = true;
                        }
                        if (bl)
                        {
                            foreach (RichTextBox rtb in spltMain.Panel2.Controls.OfType<RichTextBox>())
                            {
                                rtb.LoadFile(ofd.FileName);
                            }
                        }
                        else if (!bl)
                        {
                            RichTextBox rtb = new RichTextBox();
                            rtb.ContextMenuStrip = ctx4rtb;
                            rtb.SelectionChanged += Rtb_SelectionChanged;
                            rtb.ContentsResized += Rtb_ContentsResized;
                            rtb.TextChanged += Rtb_TextChanged;
                            rtb.Dock = DockStyle.Fill;
                            rtb.BorderStyle = BorderStyle.Fixed3D;
                            rtb.WordWrap = false;
                            rtb.ScrollBars = RichTextBoxScrollBars.Vertical;
                            rtb.Multiline = rtb.WordWrap = rtb.AutoSize = true;
                            spltMain.Panel2.Controls.Add(rtb);
                            rtb.BringToFront();
                            rtb.LoadFile(ofd.FileName);
                        }
                    }            
                }
            }

    And here's more code for the event handlers included in the block where I create a new RichTextBox...

     private static int EM_LINEINDEX = 0xbb;
            [DllImport("user32.dll")]
            extern static int SendMessage(IntPtr hwnd, int message, int wparam, int lparam);

    private void RtbMain_TextChanged(object sender, EventArgs e) { glbblProjectIsSaved = false; UpdateCaretPos(); } private void Rtb_SelectionChanged(object sender, EventArgs e) { RichTextBox rtb = sender as RichTextBox; int firstcharindex = rtb.GetFirstCharIndexOfCurrentLine(); intCurrentLine = rtb.GetLineFromCharIndex(firstcharindex) + 1; } private void Rtb_ContentsResized(object sender, ContentsResizedEventArgs e) { const int margin = 5; RichTextBox rch = sender as RichTextBox; rch.ClientSize = new System.Drawing.Size(e.NewRectangle.Width + margin, e.NewRectangle.Height + margin); }

            private void UpdateCaretPos()
            {
                foreach (RichTextBox rtb in spltMain.Panel2.Controls.OfType<RichTextBox>())
                {
                    int line, col, index;
                    index = rtb.SelectionStart;
                    line = rtb.GetLineFromCharIndex(index);
                    col = index - SendMessage(rtb.Handle, EM_LINEINDEX, -1, 0);
                    //rtbMain.Text = (++line).ToString() + ", " + (++col).ToString();
                    sslblCursorLocation.Text = "Ln " + (++line).ToString() + ", " + "Ch " + (++col).ToString();
                }
            }







    Monday, September 9, 2019 9:19 PM
  • Hi Milwaukee Broad,

    Thanks for your feedback.

    I make a test based on your code, and I make a change to the UpdateCaretPos() method.

            private void UpdateCaretPos()
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    int line, col, index;
                    index = rtb.SelectionStart;
                    line = rtb.GetLineFromCharIndex(index);
                    col = index - SendMessage(rtb.Handle, EM_LINEINDEX, -1, 0);
    
                    rtb.SelectionStart = index;
                    rtb.Focus();
    
                    sslblCursorLocation.Text = "Ln " + (++line).ToString() + ", " + "Ch " + (++col).ToString();
                }
            }

    Hope it can help you.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, September 11, 2019 9:16 AM
  • Thanks for your suggestion, Xingyu Zhao. Unfortunately, the cursor still jumps to the bottom of the RichTextBox after I make changes to the RichTextBox's contents.
    Wednesday, September 11, 2019 11:38 PM
  • Hi Milwaukee Broad,

    I make a test using the code above, but I don't have the problem that cursor jumps to the bottom of the RichTextBox.

    Here's my whole code.

            private static int EM_LINEINDEX = 0xbb;
            [DllImport("user32.dll")]
            extern static int SendMessage(IntPtr hwnd, int message, int wparam, int lparam);       
            private void Rtb_TextChanged(object sender, EventArgs e) // I change 'RtbMain' to 'Rtb'.
            {
                //glbblProjectIsSaved = false;
                UpdateCaretPos();
            }
            private void Rtb_SelectionChanged(object sender, EventArgs e)
            {
                RichTextBox rtb = sender as RichTextBox;
                int row = 1 + rtb.GetLineFromCharIndex(rtb.SelectionStart);
                int column = 1 + rtb.SelectionStart - (rtb.GetFirstCharIndexFromLine(1 + rtb.GetLineFromCharIndex(rtb.SelectionStart) - 1));
                int firstcharindex = rtb.GetFirstCharIndexOfCurrentLine();
                int intCurrentLine = rtb.GetLineFromCharIndex(firstcharindex) + 1;
            }
            private void Rtb_ContentsResized(object sender, ContentsResizedEventArgs e)
            {
                const int margin = 5;
                RichTextBox rch = sender as RichTextBox;
                rch.ClientSize = new System.Drawing.Size(e.NewRectangle.Width + margin, e.NewRectangle.Height + margin);
            }
            private void UpdateCaretPos()
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    int line, col, index;
                    index = rtb.SelectionStart;
                    line = rtb.GetLineFromCharIndex(index);
                    col = index - SendMessage(rtb.Handle, EM_LINEINDEX, -1, 0);
    
                    rtb.SelectionStart = index;
                    rtb.Focus();
                    //sslblCursorLocation.Text = "Ln " + (++line).ToString() + ", " + "Ch " + (++col).ToString();
                    textBox1.Text = "Ln " + (++line).ToString() + ", " + "Ch " + (++col).ToString();
                }
            }
            private void Button1_Click(object sender, EventArgs e)
            {
                
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Left;
                }
            }
            private void Button2_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Center;
                }
            }
            private void Button3_Click(object sender, EventArgs e)
            {
                foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                {
                    rtb.SelectionAlignment = HorizontalAlignment.Right;
                }
            }
            private void MnuOpenDocument_Click(object sender, EventArgs e)
            {
                using (OpenFileDialog ofd = new OpenFileDialog())
                {
                    ofd.Multiselect = false;
                    ofd.Title = "Open...";
                    ofd.Filter = "Rich Text Files (.rtf)|*.rtf";
                    if (DialogResult.OK == ofd.ShowDialog())
                    {
                        bool bl = false;
                        foreach (Control ctrl in this.panel1.Controls)
                        {
                            if (ctrl is RichTextBox)
                                bl = true;
                        }
                        if (bl)
                        {
                            foreach (RichTextBox rtb in this.panel1.Controls.OfType<RichTextBox>())
                            {
                                rtb.LoadFile(ofd.FileName);
                            }
                        }
                        else if (!bl)
                        {
                            RichTextBox rtb = new RichTextBox();
                            //rtb.ContextMenuStrip = ctx4rtb;
                            rtb.SelectionChanged += Rtb_SelectionChanged;
                            rtb.ContentsResized += Rtb_ContentsResized;
                            rtb.TextChanged += Rtb_TextChanged;
                            rtb.Dock = DockStyle.Fill;
                            rtb.BorderStyle = BorderStyle.Fixed3D;
                            rtb.WordWrap = false;
                            rtb.ScrollBars = RichTextBoxScrollBars.Vertical;
                            rtb.Multiline = rtb.WordWrap = rtb.AutoSize = true;
                            this.panel1.Controls.Add(rtb);
                            rtb.BringToFront();
                            rtb.LoadFile(ofd.FileName);
                        }
                    }
                }
            }

    Result of my test.

    Could you provide more code or information for us to reproduce your problem?

    Best Regrads,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, September 12, 2019 6:16 AM
  • Xingyu Zhao,

    That's about all the code I have in regards to the RichTextBox and loading and editing its contents. Apart from the changes made to the RichTextBox's properties in code, all other properties are left at their defaults. Also, the RichTextBox is a child control of a SplitContainer.Panel2 which is a child control of a Windows Form. Let me know if there are any other areas where this problem could be caused.


    Friday, September 13, 2019 7:50 PM
  • Hi Milwaukee Broad,

    I have shared my test project in the following link.

    https://1drv.ms/u/s!AhaovKAey6JLaqLrhO2hCABl69g?e=aCPjbA

    You can download and test it on your side.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, September 20, 2019 7:36 AM