Getting the cursor row and column position in a UWP TextBox


Getting the cursor row and column position in a UWP TextBox

In learning what UWP has to offer in 2019 I started putting together a clone of Notepad which I quickly deciding to start adding more functionality to. One of things I wanted to do was find the current position of the cursor in the TextBox. After about 30 minutes the below is what I ended up settling on. I ran a couple of variations of looping through the performance profiler on large documents and what's below was what I ended up on. As we don't have access to the internals of the TextBox this was best way I could figure out to get this working.

Note of course, being at the end of the string would require the loop to go much farther. I tested on a document with 12,000 rows and over 230,000 characters and it didn't seem to slow the UI down (on a 2nd generation Core i7 from 2011). In some cases we're forced to work with what we have and not what we want.

CursorPosition Extension Method

/// <summary>
/// Returns the current column position on the current line the cursor is on.
/// </summary>
public static CursorPosition CursorPosition(this TextBox tb)
{
    int endMarker = tb.SelectionStart;

    if (endMarker == 0)
    {
        return new CursorPosition(1, 1);
    }

    int i = 0;
    int col = 1;
    int row = 1;

    foreach (char c in tb.Text)
    {
        i++;
        col++;

        if (c == '\r')
        {
            row++;
            col = 1;
        }

        if (i == endMarker)
        {
            return new CursorPosition(row, col);
        }
    }

    return new CursorPosition(row, col);
}

CursorPosition Class

public class CursorPosition
{
    public CursorPosition()
    {

    }

    public CursorPosition(int row, int column)
    {
        Row = row;
        Column = column;
    }

    public int Row { get; set; } = 1;

    public int Column { get; set; } = 1;

}

Leave a comment

Please note that we won't show your email to others, or use it for sending unwanted emails. We will only use it to render your Gravatar image and to validate you as a real person.