This example enables line numbering for the first document section. Line numbering starts at number one and restarts at the new section. Numbers are displayed on each second line and are indented from the text at a distance equal to 75 documents (0.25 of an inch).
The Custom Draw technique is used to display the line number column with a color background.
Implementation Details
The Section.LineNumbering property enables line numbering for the first document section.
Set the AllowDisplayLineNumbers property to true
in the SimpleView and DraftView views to display line numbering. To make line numbers visible, the left padding is increased to 60
points.
The Line Number document style defines the used font and color.
Create a custom PagePainter descendant which implements the methods required to draw the column background and the line numbers. Handle the RichEditControl.BeforePagePaint event and set the BeforePagePaintEventArgs.Painter property to the PagePainter
descendant instance.
Create an instance of the LayoutVisitor descendant and let it traverse the page layout. When it encounters a new row, it calls the VisitRow
method. This method increments the row counter to count the lines on a page. To run the visitor each time after building the document layout, handle the DocumentLayout.DocumentFormatted event.
Files to Review
- Form1.cs (VB: Form1.vb)
- MyLayoutVisitor.cs (VB: MyLayoutVisitor.vb)
- MyPagePainter.cs (VB: MyPagePainter.vb)
Documentation
- How to: Count the Lines in the Document
- How To: Add Line Numbering in the Rich Text Editor
- How to: Set Background Color for the Line Number Column
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#//using DevExpress.XtraRichEdit.API.Layout;
//using DevExpress.XtraRichEdit.API.Native;
using DevExpress.Portable;
using DevExpress.XtraRichEdit;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LineNumberingExample {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
ribbonControl1.SelectedPage = exampleRibbonPage1;
richEditControl1.DocumentLoaded += RichEditControl1_DocumentLoaded;
richEditControl1.DocumentLayout.DocumentFormatted += DocumentLayout_DocumentFormatted;
}
private void Form1_Load(object sender, EventArgs e) {
richEditControl1.LoadDocument("Grimm.docx");
}
private void RichEditControl1_DocumentLoaded(object sender, EventArgs e) {
richEditControl1.ActiveViewType = DevExpress.XtraRichEdit.RichEditViewType.Simple;
#region #linenumbering
this.richEditControl1.Views.SimpleView.Padding = new PortablePadding(60, 4, 4, 0);
this.richEditControl1.Views.DraftView.Padding = new PortablePadding(60, 4, 4, 0);
richEditControl1.Views.SimpleView.AllowDisplayLineNumbers = true;
richEditControl1.Views.DraftView.AllowDisplayLineNumbers = true;
richEditControl1.Document.Sections[0].LineNumbering.Start = 1;
richEditControl1.Document.Sections[0].LineNumbering.CountBy = 2;
richEditControl1.Document.Sections[0].LineNumbering.Distance = 75f;
richEditControl1.Document.Sections[0].LineNumbering.RestartType = DevExpress.XtraRichEdit.API.Native.LineNumberingRestart.Continuous;
richEditControl1.Document.CharacterStyles["Line Number"].FontName = "Courier";
richEditControl1.Document.CharacterStyles["Line Number"].FontSize = 10;
richEditControl1.Document.CharacterStyles["Line Number"].ForeColor = Color.DarkGray;
richEditControl1.Document.CharacterStyles["Line Number"].Bold = true;
#endregion #linenumbering
}
#region #BeforePagePaint
private void RichEditControl1_BeforePagePaint(object sender, DevExpress.XtraRichEdit.BeforePagePaintEventArgs e) {
if (e.CanvasOwnerType == DevExpress.XtraRichEdit.API.Layout.CanvasOwnerType.Printer) {
return;
}
DevExpress.XtraRichEdit.API.Native.CharacterStyle style = richEditControl1.Document.CharacterStyles["Line Number"];
MyPagePainter customPagePainter = new MyPagePainter(richEditControl1, SystemColors.Info, style);
customPagePainter.LineNumberPadding = 60;
e.Painter = customPagePainter;
}
#endregion #BeforePagePaint
private void barCheckLineNumberBackColoring_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) {
if (barCheckLineNumberBackColoring.Checked)
richEditControl1.BeforePagePaint += RichEditControl1_BeforePagePaint;
else
richEditControl1.BeforePagePaint -= RichEditControl1_BeforePagePaint;
richEditControl1.Refresh();
}
#region #DocumentFormatted
private void DocumentLayout_DocumentFormatted(object sender, EventArgs e) {
this.BeginInvoke((MethodInvoker)(() =>
{
if (this.Visible) {
MyLayoutVisitor visitor = new MyLayoutVisitor(richEditControl1.Document);
int pageCount = richEditControl1.DocumentLayout.GetFormattedPageCount();
for (int i = 0; i < pageCount; i++) {
visitor.Visit(richEditControl1.DocumentLayout.GetPage(i));
}
resultBarStaticItem.Caption = String.Format("Document has {0} lines", visitor.RowIndex);
}
}));
}
#endregion #DocumentFormatted
}
}
C#using DevExpress.XtraRichEdit.API.Layout;
using DevExpress.XtraRichEdit.API.Native;
using System;
namespace LineNumberingExample {
#region #MyLayoutVisitor
public class MyLayoutVisitor : LayoutVisitor {
Document document;
public int RowIndex { get; private set; }
public MyLayoutVisitor(Document doc) {
this.document = doc;
RowIndex = 0;
}
protected override void VisitRow(LayoutRow row) {
RowIndex++;
base.VisitRow(row);
}
}
#endregion #MyLayoutVisitor
}
C#using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Layout;
using DevExpress.XtraRichEdit.API.Native;
using System.Drawing;
namespace LineNumberingExample {
#region #MyPagePainter
public class MyPagePainter : PagePainter {
RichEditControl richEditControl;
int previousColumnIndex = -1;
Font lineNumberFont;
public MyPagePainter(RichEditControl richEdit)
: base() {
richEditControl = richEdit;
}
public MyPagePainter(RichEditControl richEdit, Color backColor, CharacterStyle style)
: base() {
richEditControl = richEdit;
NumberingHighlightColor = backColor;
NumberingFontName = style.FontName;
NumberingFontSize = style.FontSize ?? 10F;
NumberingFontColor = style.ForeColor ?? Color.Black;
}
public string NumberingFontName { get; set; }
public float NumberingFontSize { get; set; }
public Color NumberingFontColor { get; set; }
public Color NumberingHighlightColor { get; set; }
public int LineNumberPadding { get; set; }
public override void DrawPage(LayoutPage page) {
lineNumberFont = new Font(NumberingFontName, NumberingFontSize, FontStyle.Regular);
base.DrawPage(page);
lineNumberFont.Dispose();
}
public override void DrawPageArea(LayoutPageArea pageArea) {
Rectangle lineNumberBounds = new Rectangle(new Point(-LineNumberPadding, 0), new Size(LineNumberPadding, pageArea.Bounds.Height));
Canvas.FillRectangle(new RichEditBrush(NumberingHighlightColor), lineNumberBounds);
base.DrawPageArea(pageArea);
previousColumnIndex = -1;
}
public override void DrawColumn(LayoutColumn column) {
LayoutPageArea pageArea = column.GetParentByType<LayoutPageArea>();
if (pageArea != null) {
int leftBoundary = 0;
if (previousColumnIndex >= 0) {
leftBoundary = pageArea.Columns[previousColumnIndex].Bounds.Right;
}
if (column.LineNumbers.Count > 0) {
HighlightLineNumberingArea(column, leftBoundary);
}
previousColumnIndex++;
}
base.DrawColumn(column);
}
public override void DrawLineNumberBox(LineNumberBox lineNumberBox) {
Canvas.DrawString(lineNumberBox.Text, lineNumberFont, new RichEditBrush(NumberingFontColor), lineNumberBox.Bounds, this.richEditControl.LayoutUnit);
}
void HighlightLineNumberingArea(LayoutColumn column, int leftBoundary) {
LayoutPage page = column.GetParentByType<LayoutPage>();
Rectangle marginBounds = new Rectangle(new Point(leftBoundary, 0), new Size(column.Bounds.X - leftBoundary, page.Bounds.Height));
Canvas.FillRectangle(new RichEditBrush(NumberingHighlightColor), marginBounds);
}
}
#endregion #MyPagePainter
}