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:
- By accessing
TextBox.SelectionStart
andTextBox.SelectionLength
properties. 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
Set System Time Zone from .Net
Multiple Identities in ASP.NET Core 2.0
How to Get the Name of Color While Having Its Rgb Value in C#
C# Structs: Unassigned Local Variable
C# - Asserting Two Objects Are Equal in Unit Tests
Why Is Webbrowser_Documentcompleted() Firing Twice
Dictionary <String,String> Map to an Object Using Automapper
Capture Screen on Server Desktop Session
Print HTML Document from Windows Service Without Print Dialog