获取winforms文本框的光标位置

7uhlpewt  于 2022-11-30  发布在  其他
关注(0)|答案(5)|浏览(230)

如何在.NET中获取winforms文本框的当前光标(插入符号)位置?SelectionStart只返回所选文本的开头(所选内容的左侧)。这意味着如果光标位于所选内容的右侧,则此值是错误的。
澄清一下:在.NET TextBox中,SelectionStart指向所选内容的左侧,当插入符号位于所选内容的右侧时也是如此。这意味着在这两个图片中,SelectionStart都是2,但插入符号位置在第一个图片中是2,在右侧图片中是7。

2o7dmzc5

2o7dmzc51#

如前所述,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的引用和使用。
不确定是否有一些缺点,这个解决方案和等待,如果有人更Maven可以告诉我们,如果有什么错误或不明原因。

jhdbpxl9

jhdbpxl92#

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);

另外(不是我的问题的一部分)我可以用下面的代码设置插入符号和文本选择。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的名义发布。

2wnc66cl

2wnc66cl3#

如果要选择左侧,可以使用:

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;
}
v1uwarro

v1uwarro4#

这可能会用到某人:

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;
        }
    }
}
rqqzpn5f

rqqzpn5f5#

当您在TextBox内按一下鼠标器或移动方向键按钮时,您的游标会移至新的位置,而该位置会记录在此变数中。

textBox1.SelectionStart

该值是从TextBox开头的0到光标所在位置的字符数。如果仔细编写代码,将使其正常工作。要突出显示所选内容,应使用此函数以避免混淆。

textBox1.Select(start, length);

其中

int start = textBox1.SelectionStart;
int length = textBox1.SelectionStart+textBox1.SelectionLength;

相关问题