正如已经提到的那样,使用SelectionStart
属性在TextBox中获得有选择文本时光标的真实位置是不可靠的。这是由于该属性始终指向选定文本的起始位置(提示:名称不会说谎),并且根据您使用鼠标选择文本的方式,光标可能位于选择的左侧或右侧。
下面的代码(在LinqPAD中测试)展示了另一种方法:
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);
}
GetCaretPos
返回光标所在位置的客户端坐标。您可以使用托管方法 GetCharIndexFromPosition
返回该位置后字符的索引。当然,您需要添加对 System.Runtime.InteropServices
的引用和使用。不确定此解决方案是否存在一些缺点,等待更专业的人士告诉我们是否存在错误或未考虑到的问题。有了Steve的答案,现在这是我的解决方案:
[DllImport("user32")]
private extern static int GetCaretPos(out Point p);
...
// get current caret position
Point caret;
GetCaretPos(out caret);
int caretPosition = tbx.GetCharIndexFromPosition(caret);
// determine if current caret is at beginning
bool caretAtBeginning = tbx.SelectionStart == caretIndex;
...
// set text selection and caret position
if (caretAtBeginning)
tbx.Select(selStart + selLength, -selLength);
else
tbx.Select(selStart, selLength);
textBox1.SelectionStart
该值是从TextBox开头到光标位置的字符计数,从0开始。如果您仔细编写代码,它将正确工作。为了突出选择,您应该使用此功能以避免混淆。
textBox1.Select(start, length);
在哪里
int start = textBox1.SelectionStart;
int length = textBox1.SelectionStart+textBox1.SelectionLength;
int lastSelectionStart = 0;
int getCaretPosition()
{
if (tbx.SelectionLength == 0)
{
lastSelectionStart = tbx.SelectionStart;
return lastSelectionStart;
}
else
{
if (tbx.SelectionStart == lastSelectionStart)
{
return tbx.SelectionStart + tbx.SelectionLength;
}
else
{
return lastSelectionStart - tbx.SelectionLength;
}
}
}
int index = textBox.SelectionStart;
如果你想要选择区域的右侧,可以使用以下代码:
int index = textBox.SelectionStart + textBox.SelectionLength;
// On mouse down event.
int mouseDownX = MousePosition.X;
// On mouse up event.
int mouseUpX = MousePosition.X;
// Check direction.
if(mouseDownX < mouseUpX)
{
// Left to Right selection.
int index = textBox.SelectionStart;
}
else
{
// Right to Left selection.
int index = textBox.SelectionStart + textBox.SelectionLength;
}
SelectionStart + SelectionLength
有帮助吗? - Sriram Sakthivel