8

I'm porting an application from WinForms to WPF and I've hit a snag while trying to get the line and column number for where the selection is in the text box. I was able to do it quite simply in WinForms but WPF has a completely different way of implementing a RichTextBox so I have no idea how to go about it.

Here is my WinForms solution

int line = richTextBox.GetLineFromCharIndex(TextBox.SelectionStart);
int column = richTextBox.SelectionStart - TextBox.GetFirstCharIndexFromLine(line);

LineColumnLabel.Text = "Line " + (line + 1) + ", Column " + (column + 1);

This won't work with WPF because you can't get the index of the current selection.

HERE IS THE WORKING SOLUTION:

int lineNumber;
textBox.CaretPosition.GetLineStartPosition(-int.MaxValue, out lineNumber);
int columnNumber = richTextBox.CaretPosition.GetLineStartposition(0).GetOffsetToPosition(richTextBox.CaretPosition);
if (lineNumber == 0)
    columnNumber--;

statusBarLineColumn.Content = string.Format("Line {0}, Column {1}", -lineNumber + 1, columnNumber + 1);
Joseph Little
  • 921
  • 3
  • 13
  • 22
  • Have you tried something, to tell how it is completely different? – provençal le breton Aug 01 '13 at 12:59
  • Likely related: http://stackoverflow.com/questions/957441/richtextbox-wpf-does-not-have-string-property-text?rq=1 – Will Eddins Aug 01 '13 at 13:03
  • You'll need to look up dependencies but, this is not an easy task. I did look into this, saw how much work was needed (or at least how much I needed to learn) and changed my product spec so I could avoid it! You may be best looking for a third party if time is essential to your project. – Dave Aug 01 '13 at 13:04
  • updated with my WinForms solution @Will I can get the text from the box but I can't get where the selector is, plus I'd have to work out how many lines/columns it had passed and Dave that's a shame :( – Joseph Little Aug 01 '13 at 13:07

2 Answers2

8

Something like this may give you a starting point.

TextPointer tp1 = rtb.Selection.Start.GetLineStartPosition(0);
TextPointer tp2 = rtb.Selection.Start;

int column = tp1.GetOffsetToPosition(tp2);

int someBigNumber = int.MaxValue;
int lineMoved, currentLineNumber;
rtb.Selection.Start.GetLineStartPosition(-someBigNumber, out lineMoved);
currentLineNumber = -lineMoved;

LineColumnLabel.Content = "Line: " + currentLineNumber.ToString() + " Column: " + column.ToString();

A couple things to note. The first line will be line 0 so you may want to add a + 1 to the line number. Also if a line wraps its initial column will be 0 but the first line and any line following a CR will list the initial position as column 1.

Sisco
  • 111
  • 2
  • 1
    Thanks! Your answer really helped. I had to do one little thing which was minus 1 from the column if the line number was 1. I'm going to post my working solution – Joseph Little Aug 01 '13 at 13:37
0

To get the real absolute line number (wrapped lines are not counted):

Paragraph currentParagraph = rtb.CaretPosition.Paragraph;

// the text becomes either currently selected and the selection reachted the end of the text or the text does not contain any data at all
if (currentParagraph == null)
{
    currentParagraph = rtb.Document.ContentEnd.Paragraph;
}

lineIndexAbsolute = Math.Max(rtb.Document.Blocks.IndexOf(currentParagraph), 0);
marsh-wiggle
  • 2,508
  • 3
  • 35
  • 52