我有一個多行文本框,它根據給出的數據顯示一些值(通常每行一個值)。 (爲了讓工具提示彈出一些「替代」數據),我希望得到鼠標懸停在其上的單詞(或者至少是行),以便我可以找到替代方案顯示。如何根據鼠標位置從文本框中獲取特定文本值
我有一些想法,如何使用基於文本框和字體大小的計算來做到這一點,但我不會沿着這條路走下去,因爲大小和字體可能會頻繁變化。
那麼...有沒有使用鼠標位置來抓取特定文本框文本的方法?
我有一個多行文本框,它根據給出的數據顯示一些值(通常每行一個值)。 (爲了讓工具提示彈出一些「替代」數據),我希望得到鼠標懸停在其上的單詞(或者至少是行),以便我可以找到替代方案顯示。如何根據鼠標位置從文本框中獲取特定文本值
我有一些想法,如何使用基於文本框和字體大小的計算來做到這一點,但我不會沿着這條路走下去,因爲大小和字體可能會頻繁變化。
那麼...有沒有使用鼠標位置來抓取特定文本框文本的方法?
這是另一種解決方案。將此MouseMove事件添加到TextBox中:
private void txtHoverWord_MouseMove(object sender, MouseEventArgs e)
{
if (!(sender is TextBox)) return;
var targetTextBox = sender as TextBox;
if(targetTextBox.TextLength < 1) return;
var currentTextIndex = targetTextBox.GetCharIndexFromPosition(e.Location);
var wordRegex = new Regex(@"(\w+)");
var words = wordRegex.Matches(targetTextBox.Text);
if(words.Count < 1) return;
var currentWord = string.Empty;
for (var i = words.Count - 1; i >= 0; i--)
{
if (words[i].Index <= currentTextIndex)
{
currentWord = words[i].Value;
break;
}
}
if(currentWord == string.Empty) return;
toolTip.SetToolTip(targetTextBox, currentWord);
}
使用GetCharIndexFromPosition方法將鼠標的位置映射到整個文本中的索引。從那個位置開始,左右都有進展,直到你有整個單詞。
要獲取鼠標位置,請使用MouseHover事件,以便在每次都不是每次都會得到它(這會讓事情變得緩慢)。
謝謝。我對你在mousemove上使用鼠標懸停事件的建議進行了討論,它使得這個效果更加用戶友好。謝謝你的幫助。 – Jammerz858
我的解決方案使用一個技巧來實現你想要的。
當您在文本區域內雙擊時,它會選擇基礎單詞。
因此,在窗體上使用RichTextBox
(TextBox
確實在鼠標事件上閃爍),您可以在單擊鼠標中鍵(類似巴比倫字典)時模擬雙擊。如果你想要,你也可以使用MouseHover
而不是MouseDown
。有用。
public partial class Form3 : Form
{
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
public Form3()
{
InitializeComponent();
timer.Interval = 50;
timer.Tick += timer_Tick;
}
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
MessageBox.Show(richTextBox1.SelectedText);
// do more stuff here, e.g display your tooltip for the selected word or anything else
richTextBox1.SelectionLength = 0; // remove the highlighted color of selection
}
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
private const uint MOUSEEVENTF_LEFTUP = 0x04;
private const uint MOUSEEVENTF_RIGHTDOWN = 0x08;
private const uint MOUSEEVENTF_RIGHTUP = 0x10;
public void DoMouseDoubleClick()
{
//Call the imported function with the cursor's current position
uint X = (uint)Cursor.Position.X;
uint Y = (uint)Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN, X, Y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN, X, Y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
timer.Start(); // some delay is required so that mouse event reach to RichTextBox and the word get selected
}
private void richTextBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Middle)
{
DoMouseDoubleClick();
}
}
}
非常酷的解決方案...但有點太複雜的要求。儘管謝謝你的幫助。 – Jammerz858
謝謝,這工作出色!我喜歡用正則表達式來踢出白色空間! :) – Jammerz858
很高興你喜歡它。請注意,它不會簡單地刪除空白區域。它只保留了正則表達式認爲的一個單詞,所以標點符號和其他任何不被視爲單詞的內容都被刪除。 –