2012-10-25 98 views
10

我有一個多行文本框,它根據給出的數據顯示一些值(通常每行一個值)。 (爲了讓工具提示彈出一些「替代」數據),我希望得到鼠標懸停在其上的單詞(或者至少是行),以便我可以找到替代方案顯示。如何根據鼠標位置從文本框中獲取特定文本值

我有一些想法,如何使用基於文本框和字體大小的計算來做到這一點,但我不會沿着這條路走下去,因爲大小和字體可能會頻繁變化。

那麼...有沒有使用鼠標位置來抓取特定文本框文本的方法?

回答

6

這是另一種解決方案。將此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); 
} 
+0

謝謝,這工作出色!我喜歡用正則表達式來踢出白色空間! :) – Jammerz858

+0

很高興你喜歡它。請注意,它不會簡單地刪除空白區域。它只保留了正則表達式認爲的一個單詞,所以標點符號和其他任何不被視爲單詞的內容都被刪除。 –

3

使用GetCharIndexFromPosition方法將鼠標的位置映射到整個文本中的索引。從那個位置開始,左右都有進展,直到你有整個單詞。

要獲取鼠標位置,請使用MouseHover事件,以便在每次都不是每次都會得到它(這會讓事情變得緩慢)。

+0

謝謝。我對你在mousemove上使用鼠標懸停事件的建議進行了討論,它使得這個效果更加用戶友好。謝謝你的幫助。 – Jammerz858

2

我的解決方案使用一個技巧來實現你想要的。

當您在文本區域內雙擊時,它會選擇基礎單詞。

因此,在窗體上使用RichTextBoxTextBox確實在鼠標事件上閃爍),您可以在單擊鼠標中鍵(類似巴比倫字典)時模擬雙擊。如果你想要,你也可以使用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(); 
      } 
     } 
    } 
+0

非常酷的解決方案...但有點太複雜的要求。儘管謝謝你的幫助。 – Jammerz858

相關問題