获取winforms文本框

时间:2015-08-18 08:29:24

标签: c# .net winforms

如何在.NET中获取winforms文本框的当前光标(插入符号)位置? SelectionStart仅返回所选文本的开头(选择的左侧)。如果光标位于选择的右侧,则表示此值错误。

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

enter image description here

4 个答案:

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