簡體   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