我有一个多行文本框,它根据给定的数据显示一些值(通常每行一个值)。
(为了让工具提示弹出一些“替代”数据)我想得到鼠标悬停在上面的单词(或至少是行),这样我就可以找到要显示的替代方法。
我对如何根据文本框和字体大小进行计算有一些想法,但我不知道该怎么做,因为大小和字体可能会经常变化。
那么...有没有办法使用鼠标位置来获取特定的文本框文本?
我有一个多行文本框,它根据给定的数据显示一些值(通常每行一个值)。
(为了让工具提示弹出一些“替代”数据)我想得到鼠标悬停在上面的单词(或至少是行),这样我就可以找到要显示的替代方法。
我对如何根据文本框和字体大小进行计算有一些想法,但我不知道该怎么做,因为大小和字体可能会经常变化。
那么...有没有办法使用鼠标位置来获取特定的文本框文本?
这是一个替代解决方案。将此 MouseMove 事件添加到您的文本框:
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方法将鼠标的位置映射到整个 Text 中的索引。从那个位置开始,左右前进,直到你掌握了整个单词。
要获取鼠标位置,请使用MouseHover事件,这样您就可以在它静止时而不是每次都得到它(这会使事情变慢)。
我的解决方案使用一个技巧来实现你想要的。
当您在文本区域内双击时,它会选择基础单词。
因此,在您的表单上使用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();
}
}
}