Implementing Paging in RichTextBox






4.43/5 (5 votes)
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
asNone
. 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
yourRichTextBox
can accomodate. Maximum
that aRichTextBox
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. {figures11 and 65
corresponds to theNumber of Lines and Number of Characters
respectively. It will vary according to theRichTextBox
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 a
Dictionary
which will have page numbers and data corresponding to that page. - We also need an index to locate the
current page
loded inRichtextBox
. - 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 the paged 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 button
s, we can create one 4 button
s and can add the button
s 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 button
s 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