繁体   English   中英

获取winforms文本框的cursor position

[英]Get cursor position of winforms textbox

如何获取 .NET 中 winforms 文本框的当前 cursor(插入符号)position? SelectionStart 仅返回所选文本的开始(选择的左侧)。 如果 cursor 在选择的右侧,则意味着此值是错误的。


澄清一下:在 .NET 中,TextBox SelectionStart 指向选择的左侧,当插入符号位于选择的右侧时也是如此。 这意味着在两张图片中 SelectionStart 都是 2,但插入符号 position 在第一张图片中是 2,而在右图中是 7。

在此处输入图像描述

如前所述, SelectionStart属性对于在选择活动的文本框中获取实际 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的引用和使用。

不确定这个解决方案是否有一些缺点,如果有更专业的人可以告诉我们是否有问题或下落不明。

有了史蒂夫的回答,这就是我的解决方案:

[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 发布。

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

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

这可能对某人有用:

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

当您在 TextBox 中单击鼠标或移动箭头键按钮时,您的 cursor 将被移动到一个新位置,该位置将记录在此变量中。

textBox1.SelectionStart

该值是字符计数,从 TextBox 开头的 0 开始到您的 cursor 的位置。如果您仔细编码,就会使其正常工作。 要突出显示选择,您应该使用此 function 以避免混淆。

textBox1.Select(start, length);

在哪里

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM