Click here to Skip to main content
Click here to Skip to main content

Richer RichTextBox (Part 2)

, 13 Jan 2006
Rate this:
Please Sign up or sign in to vote.
An article on extending the RichTextBox class in C#.

Sample Image

Introduction

In the first part, we extended the RichTextBox class with methods that change the FontStyle of a selection without losing the styles that are currently present. Unfortunately, there are a few more features missing from the RichTextBox control that could potentially be useful in word-processor-like applications. These kinds of applications commonly use a status bar to display information about the current cursor position. In this part, we will enrich the RichTextBox control with functionality that can be used for that purpose.

Usage

When nothing is selected, we want to display line number, column number and cursor position. When some portion of text is selected, the status bar should display the start, end and length of the selection. Also, from the client perspective, those features should be self-documentary and easy to use.

this.rtb.CursorPositionChanged += 
    new System.EventHandler(this.rtb_CursorPositionChanged);
this.rtb.SelectionChanged += 
    new System.EventHandler(this.rtb_SelectionChanged);
.
.
.
private void rtb_CursorPositionChanged(object sender, System.EventArgs e)
{
    int line = rtb.CurrentLine;
    int col = rtb.CurrentColumn;
    int pos = rtb.CurrentPosition;
    
    statusBar.Text = "Line " + line + ", Col " + col + 
                     ", Position " + pos;
}

private void rtb_SelectionChanged(object sender, System.EventArgs e)
{
    int start = rtb.SelectionStart;
    int end = rtb.SelectionEnd;
    int length = rtb.SelectionLength;
    
    statusBar.Text = "Start " + start + ", End " + end + 
                     ", Length " + length;
}

To achieve such behavior, we need to extend the RichTextBox class in the following manner:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Nik.UserControls
{
    public class RicherTextBox2 : System.Windows.Forms.RichTextBox
    {
        public event EventHandler CursorPositionChanged;
        
        protected virtual void OnCursorPositionChanged( EventArgs e )
        {
            if ( CursorPositionChanged != null )
                CursorPositionChanged( this, e );
        }

        protected override void OnSelectionChanged( EventArgs e )
        {
            if ( SelectionLength == 0 )
                OnCursorPositionChanged( e );
            else
                base.OnSelectionChanged( e );
        }
            
        public int CurrentColumn
        {
            get { return CursorPosition.Column( this, SelectionStart ); }
        }

        public int CurrentLine
        {
            get { return CursorPosition.Line( this, SelectionStart ); }
        }

        public int CurrentPosition
        {
            get { return this.SelectionStart; }
        }

        public int SelectionEnd
        {
            get { return SelectionStart + SelectionLength; }
        }
    }
    
    internal class CursorPosition
    {
        [System.Runtime.InteropServices.DllImport("user32")] 
        public static extern int GetCaretPos(ref Point lpPoint);

        private static int GetCorrection(RichTextBox e, int index)
        {
            Point pt1 = Point.Empty;
            GetCaretPos(ref pt1);
            Point pt2 = e.GetPositionFromCharIndex(index);

            if ( pt1 != pt2 )
                return 1;
            else
                return 0;
        }

        public static int Line( RichTextBox e, int index )
        {
             int correction = GetCorrection( e, index );
             return e.GetLineFromCharIndex( index ) - correction + 1;
        }

        public static int Column( RichTextBox e, int index1 )
        {
             int correction = GetCorrection( e, index1 );
             Point p = e.GetPositionFromCharIndex( index1 - correction );

             if ( p.X == 1 )
                 return 1;

             p.X = 0;
             int index2 = e.GetCharIndexFromPosition( p );

             int col = index1 - index2 + 1;

             return col;
         }
    }
}

Resources

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

About the Author

Nikola Stepan
Software Developer
Croatia Croatia
No Biography provided

Comments and Discussions

 
GeneralSet Cursor Position PinmemberSallac7-Mar-08 0:23 
GeneralFinding Text Position Pinmembermark_e_mark30-Mar-06 4:49 
GeneralProblem with column position Pinmembergijsvennix2-Jan-06 1:29 
GeneralRe: Problem with column position PinmemberNikola Stepan13-Jan-06 3:46 
GeneralRe: Problem with column position PinmemberRibeaucoup Thomas13-Dec-06 22:05 
GeneralRe: Problem with column position Pinmembermahone20-Jul-09 5:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140709.1 | Last Updated 13 Jan 2006
Article Copyright 2005 by Nikola Stepan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid