Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Implementing Paging in RichTextBox

0.00/5 (No votes)
1 Jun 2016 3  
How to achieve paging feature in RichTextBox of Windows Forms

Introduction

Currently, the RichTextBox control of Windows Form has no feature of paging. So, this tip will illustrate how to achieve paging within RichTextBox.

Background

We will be creating a UserControl, which will have the buttons to scroll through various pages and the RichTextBox control.

Using the Code

So we will create a UserControl.

  • It will consists of two Panels, one panel will Contain the buttons. The other Panel will be a parent panel, which will contain the ButtonPanel and RichTextBox.
  • Button Panel will contain the First button , Last button, >> button & << button for navigation.

The Logic behind the code:

The requirement is to create a fixed size RichtextBox in which we are able to see the data in forms of page rather than scrolling the RichTextBox. To Implement the same points that should be kept in mind:

  • Make the RichTextBox scrollBars as None. So that scrolling is disabled.
  • Make the size of RichTextBox predefined andFixed.
  • Calculate the number of character a single line can accomodate [Do count the spaces].
  • Calculate the number of lines your RichTextBox can accomodate.
  • Maximum that a RichTextBox will accomadate will be {Number of Lines * Number of Characters}.
  • // In My case -> lines*maxChar[11*65]
                int maxLength = 715;
  • Now Calculate the number of pages, you will need to show the data in form of pages. By checking the length of the data you are receiving is more than the maximum your RichTextBox can accomodate.
  • int noOfPages = 0;
    
                if (data.Length > maxLength)
                {
                    string noPages = Math.Round((Convert.ToDouble(data.Length) / maxLength), 2).ToString();
    
                   //Check If the division yeild the Accurate or the decimal result.
                    if (noPages.Contains("."))
                    {
                        var noPagesArr = noPages.Split('.');
    // If the number after decimal is more than 0, we need to create another page.
                        noOfPages = Convert.ToInt32(noPagesArr[1]) > 0 ? Convert.ToInt32(noPagesArr[0]) + 1 : Convert.ToInt32(noPagesArr[0]);
                    }
                    else
                    {
                        noOfPages = Convert.ToInt16(noPages);
                    }
  • We also need to take care of BlankLines (if any), So that our RichTextBox, can accomodate properly. Below is the code snippet for the same. {figures 11 and 65 corresponds to the Number of Lines and Number of Characters respectively. It will vary according to the RichTextBox Size.}
  • //Adjust the pages for blanklines
                if (data.Contains("\r\n"))
                {
                    string[] stringSeparators = new string[] { "\r\n" };
                    string[] lines = data.Split(stringSeparators, StringSplitOptions.None);
                    var count = lines.Where(i => i.Equals("") || i.Equals(" ")).Count();
    
                    if(count>0) maxLength = (11 - lines.Length/count) * 65;
                }
  • So once the calculation is done, we need to Create aDictionary which will have page numbers and data corresponding to that page.
  • We also need an index to locate the current page loded in RichtextBox
  • And if the data we are receiving is smaller in length as compared to the capacity of the RichTextBox, then we need not do anything, just dump the data and Disable the button.

Now lets join all the pieces of data together and look at the code as a whole. It contains the full logic and will create thepaged view of RichTextBox.

 public partial class RTBWithPaging : UserControl
    {
        //A dictionary to save the Page Number with the text.

        private Dictionary<int, string> pgDatadic = new Dictionary<int, string>();
        private int currentPage = 0;

        public RTBWithPaging()
        {
            InitializeComponent();
        }

        /// <summary>
        /// This method will take the full text to be displayed, and in this function, we will create
        /// the page-Data dictionary.
        /// </summary>
        /// <param name="text">Text that you need to show</param>
        public void CalculateRTBPages(string text)
        {
            var data = text.Trim();
            // You can check for your RichTextBox, how much it can accommodate without any scroll
            // and set the maxLength accordingly.
            // In My case -> lines*maxChar[11*65]
            int maxLength = 715;

            //Adjust the pages for blanklines
            if (data.Contains("\r\n"))
            {
                string[] stringSeparators = new string[] { "\r\n" };
                string[] lines = data.Split(stringSeparators, StringSplitOptions.None);
                var count = lines.Where(i => i.Equals("") || i.Equals(" ")).Count();

                if(count >0) maxLength = (11 - lines.Length/count) * 65;
            }

            int noOfPages = 0;

            if (data.Length > maxLength)
            {
                string noPages = Math.Round((Convert.ToDouble(data.Length) / maxLength), 2).ToString();

               //Check If the division yeild the Accurate or the decimal result.
                if (noPages.Contains("."))
                {
                    var noPagesArr = noPages.Split('.');
                    // If the number after decimal is more than 0, we need to create another page.
                    noOfPages = Convert.ToInt32(noPagesArr[1]) > 0 ? Convert.ToInt32(noPagesArr[0]) + 1 : Convert.ToInt32(noPagesArr[0]);
                }
                else
                {
                    noOfPages = Convert.ToInt16(noPages);
                }
                int pos = 0;

                
                for (int p = 0; p < noOfPages; p++)
                {
                    //for the last page to accomodate the left characters.
                    if(p == noOfPages-1)
                    {
                        maxLength = data.Length - pos;
                    }
                    var substring = data.Substring(pos, maxLength);

                    //Add the page number and Data to the page.
                    pgDatadic.Add(p, substring);
                    pos += maxLength;
                }

                rtbNotes.Text = pgDatadic[0];
                currentPage = 0;
            }
            else {
                rtbNotes.Text = data;
                btnFirst.Enabled = false;
                btn_Prev.Enabled = false;
                btnNext.Enabled = false;
                btnLast.Enabled = false;
            }
            
        }

        //Buttons section.

        private void btnFirst_Click(object sender, EventArgs e)
        {
            rtbNotes.Text = pgDatadic[0];
            currentPage = 0;
        }

        private void btnLast_Click(object sender, EventArgs e)
        {
            rtbNotes.Text = pgDatadic[pgDatadic.Count - 1];
            currentPage = pgDatadic.Count - 1;
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            if (currentPage != pgDatadic.Last().Key)
            {
                rtbNotes.Text = pgDatadic[currentPage + 1];
                currentPage = currentPage + 1;
            }
        }

        private void btn_Prev_Click(object sender, EventArgs e)
        {
            if (currentPage != 0)
            {
                rtbNotes.Text = pgDatadic[currentPage - 1];
                currentPage = currentPage - 1;
            }
        }
    }
}

So the above code tells about the Code View.

Now let's take a look at the designer View:

Remember to make the scrollBars as None. It will not provide any scrollbars. And Paging can be achieved.

this.rtbNotes.BackColor = System.Drawing.SystemColors.Info;
this.rtbNotes.Dock = System.Windows.Forms.DockStyle.Fill;
this.rtbNotes.Font = new System.Drawing.Font("Microsoft Sans Serif",
12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.rtbNotes.ForeColor = System.Drawing.Color.OliveDrab;
this.rtbNotes.Location = new System.Drawing.Point(0, 40);
this.rtbNotes.Name = "rtbNotes";
this.rtbNotes.ReadOnly = true;
this.rtbNotes.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None;
this.rtbNotes.Size = new System.Drawing.Size(453, 286);
this.rtbNotes.TabIndex = 1;

Now for the buttons, we can create one 4 buttons and can add the buttons in a panel and put the RichtextBox and button Panel in a panel inside the UserControl.

this.pnlButtons.Controls.Add(this.btn_Prev);
this.pnlButtons.Controls.Add(this.btnNext);
this.pnlButtons.Controls.Add(this.btnLast);
this.pnlButtons.Controls.Add(this.btnFirst);
this.pnlButtons.Controls.Add(this.label1);
this.pnlButtons.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlButtons.Location = new System.Drawing.Point(0, 0);
this.pnlButtons.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.pnlButtons.Name = "pnlButtons";
this.pnlButtons.Size = new System.Drawing.Size(453, 40);
this.pnlButtons.TabIndex = 0

The panel containing the buttons and RichtextBox can be added. As displayed in the Image.

Clicking on First button will take you the first page. Clicking on ">>" will take you to the Next page. Clicking on "<<" will take you to the previous page and clicking on "Last" will take you to the end page.

Now you can send any text from your actual class and enjoy paging !!!!

History

  • 31st May, 2016: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here