如何在.NET中获取winforms文本框的当前光标(插入符号)位置? SelectionStart仅返回所选文本的开头(选择的左侧)。如果光标位于选择的右侧,则表示此值错误。
澄清:在.NET TextBox中,SelectionStart指向选择的左侧,也就是当插入符号位于选择的右侧时。这意味着在两张图片中SelectionStart都是2,但插入位置在第一张图片中为2,在右图片中为7。
答案 0 :(得分:3)
如前所述,SelectionStart
属性在选择处于活动状态的TextBox中获取实际CARET位置是不可靠的。这是因为这个属性始终指向选择开始(线索:名称并不是谎言),并且根据您使用鼠标选择文本的方式,插入符可以位于左侧或右侧。选择。
此代码(使用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);
}
API GetCaretPos
返回CARET所在的客户端坐标中的点。您可以使用托管方法GetCharIndexFromPosition
返回位置后面的字符索引。当然,您需要向System.Runtime.InteropServices
添加引用和使用。
不确定此解决方案是否存在某些缺点,并等待更多专家可以告诉我们是否有错误或下落不明。
答案 1 :(得分:0)
如果您想要选择的左侧,您可以使用:
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;
}
答案 2 :(得分:0)
有了史蒂夫的答案,这现在是我的解决方案:
[DllImport("user32")]
private extern static int GetCaretPos(out Point p);
...
// get current caret position
Point caret;
GetCaretPos(out caret);
int caretPosition = tbx.GetCharIndexFromPosition(caret);
另外(不是我的问题的一部分),我可以使用以下代码设置插入符号和文本选择。 user32.dll中还有一个SetCaret函数,该函数对我不起作用。但是令人惊讶的是,Select()函数支持选择长度为负值。
// 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);
注意:此帖子是从问题中摘录并代表OP张贴的。
答案 3 :(得分:0)
这可能会被某些人使用:
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;
}
}
}