How to Find the Position of a Cursor in a Text Box? C#

How do I find the position of a cursor in a text box? C#

Regardless of whether any text is selected, the SelectionStart property represents the index into the text where you caret sits. So you can use String.Insert to inject some text, like this:

myTextBox.Text = myTextBox.Text.Insert(myTextBox.SelectionStart, "Hello world");

Get cursor position of winforms textbox

As already stated, the SelectionStart property is not reliable to get the actual CARET position in a TextBox with a selection active. This is caused by the fact that this property points always at the selection start (clue: the name doesn't lie) and depending on how you select the text with the mouse the caret could be positioned on the LEFT or RIGHT side of the selection.

This code (tested with LinqPAD) shows an alternative

public class WinApi
{
[DllImport("user32.dll")]
public static extern bool GetCaretPos(out System.Drawing.Point lpPoint);
}

TextBox t = new TextBox();
void Main()
{
Form f = new Form();
f.Controls.Add(t);
Button b = new Button();
b.Dock = DockStyle.Bottom;
b.Click += onClick;
f.Controls.Add(b);
f.ShowDialog();
}

// Define other methods and classes here
void onClick(object sender, EventArgs e)
{
Console.WriteLine("Start:" + t.SelectionStart + " len:" +t.SelectionLength);
Point p = new Point();
bool result = WinApi.GetCaretPos(out p);
Console.WriteLine(p);
int idx = t.GetCharIndexFromPosition(p);
Console.WriteLine(idx);
}

The API GetCaretPos returns the point in client coordinates where the CARET is. You could return the index of the character after the position using the managed method GetCharIndexFromPosition. Of course you need to add a reference and a using to System.Runtime.InteropServices.

Not sure if there is some drawback to this solution and waiting if someone more expert can tell us if there is something wrong or unaccounted for.

How To Find The Caret Position In A TextBox Using C#?

Based on your edited question, I checked the code and found that when caret is at last character, the function gives empty position so I changed a bit, the following Functions should give you what you want:

 namespace DEMO_Apps
{
public partial class MainForm : Form
{
int xpos;
int ypos;
public MainForm()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
var o = Utility.GetCaretPoint(textBox1);
xpos = o.X;
ypos = o.Y;
textBox2.Text = Convert.ToString(xpos + "," + ypos);
}
}

public static class Utility
{
///for System.Windows.Forms.TextBox
public static System.Drawing.Point GetCaretPoint(System.Windows.Forms.TextBox textBox)
{
int start = textBox.SelectionStart;
if (start == textBox.TextLength)
start --;

return textBox.GetPositionFromCharIndex(start);
}

///for System.Windows.Controls.TextBox requires reference to the following dlls: PresentationFramework, PresentationCore & WindowBase.
//So if not using those dlls you should comment the code below:

public static System.Windows.Point GetCaretPoint(System.Windows.Controls.TextBox textBox)
{
return textBox.GetRectFromCharacterIndex(textBox.SelectionStart).Location;
}
}
}

How to capture the cursor position in a textbox?

You can use myTextBox.CaretIndex.

private void MyMethod(object sender, EventArgs e)
{
if (myTextBox.Text.Length == myTextBox.MaxLength)
{
System.Diagnostics.Debug.WriteLine($"caret is at {myTextBox.CaretIndex}");
}
}

Write absolute mouse position in TextBox

I was able to achieve this result using Cursor.Position:

A Point that represents the cursor's position in screen coordinates.

Example

using System.Windows;

namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void textBox_GotFocus(object sender, RoutedEventArgs e)
{
var postion = System.Windows.Forms.Cursor.Position;
textBox.Text = string.Format($"{postion.X}, {postion.Y}");
}
}
}

You can see from the the Microsoft reference source that Cursor.Position is defined as:

public static Point Position {
get {
NativeMethods.POINT p = new NativeMethods.POINT();
UnsafeNativeMethods.GetCursorPos(p);
return new Point(p.x, p.y);
}
set {
IntSecurity.AdjustCursorPosition.Demand();
UnsafeNativeMethods.SetCursorPos(value.X, value.Y);
}
}

So just like in yan yankelevich's answer, it still uses SetCursorPos, but this way it is easier to call.

Apart from that it probably just depends on whether or not you are happy to include the reference to System.Windows.Forms.

Setting cursor at the end of any text of a textbox

For Windows Forms you can control cursor position (and selection) with txtbox.SelectionStart and txtbox.SelectionLength properties. If you want to set caret to end try this:

txtbox.SelectionStart = txtbox.Text.Length;
txtbox.SelectionLength = 0;

For WPF see this question.

How to get Keyboard cursor position as Point in textbox

In WPF TextBox you can get caret position in multiple ways:

  1. By accessing TextBox.SelectionStart and TextBox.SelectionLength properties.
  2. TextBox.CaretIndex property.

Unfortunately there is no GetPositionFromCharIndex in TextBox so you'll have to do a little trick using GetRectFromCharacterIndex to get starting point for intellisense:

var rect = rtb.GetRectFromCharacterIndex(rtb.CaretIndex);
var point = rect.BottomRight;

Note: We are using BottomRight to make put intellisense in proper place.

How to set TextBox cursor position without SelectionStart

I have found the solution!

        // save current cursor position and selection 
int start = textBox.SelectionStart;
int length = textBox.SelectionLength;

Point point = new Point();
User32.GetCaretPos(out point);

// update text
textBox.Text = value;

// restore cursor position and selection
textBox.Select(start, length);
User32.SetCaretPos(point.X, point.Y);

Now its working just like it should.



Related Topics



Leave a reply



Submit