2012-10-25 19 views
10

Ho una casella di testo su più righe che visualizza alcuni valori in base ai dati che vengono dati, (Generalmente un valore per riga).Come ottenere un valore di testo specifico da una casella di testo in base alla posizione del mouse

(Con lo scopo di avere un popup di suggerimento con alcuni dati "alternativi") vorrei ottenere la parola (o almeno la linea) su cui il mouse passa sopra in modo da poter quindi trovare quale alternativa da visualizzare.

Ho alcune idee su come eseguire questa operazione con i calcoli basati sulla casella di testo e sulle dimensioni dei caratteri, ma non riesco a descriverlo in questa direzione in quanto le dimensioni e i caratteri potrebbero cambiare di frequente.

Quindi ... Esiste un modo per utilizzare la posizione del mouse per afferrare il testo di una casella di testo specifica?

risposta

6

Ecco una soluzione alternativa. Aggiungi questo evento MouseMove al tuo 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

grazie, questo funziona brillantemente! Mi è piaciuta anche la regex usata per dare il calcio allo spazio bianco! :) – Jammerz858

+0

Felice che ti sia piaciuto. Si noti che non rimuove semplicemente lo spazio bianco. Mantiene solo ciò che Regex considera una parola, quindi la punteggiatura e qualsiasi altra cosa che non viene considerata una parola viene rimossa. –

3

Utilizzare il metodo GetCharIndexFromPosition per mappare la posizione del mouse su un indice nell'intero testo. Da quella posizione, progredisci a sinistra e a destra finché non hai la parola intera.

Per ottenere la posizione del mouse, utilizzare l'evento MouseHover, in modo da ottenerlo solo quando è fermo e non ogni volta (ciò renderebbe le cose lente).

+0

Grazie. Sono andato con il tuo suggerimento di utilizzare l'evento di passaggio del mouse su Mousemove e rende l'effetto molto più user friendly. Grazie per l'aiuto. – Jammerz858

2

La mia soluzione utilizza un trucco per ottenere ciò che desideri.

Quando si fa doppio clic all'interno di un'area di testo, si seleziona la parola sottostante.

Quindi utilizzando un RichTextBox (TextBox lampeggia sugli eventi del mouse) sul modulo è possibile simulare il doppio clic quando si fa clic sul pulsante centrale del mouse (qualcosa come il dizionario Babylon). Se lo desideri, puoi utilizzare MouseHover invece di MouseDown. Funziona.

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

Soluzione piuttosto interessante ... ma un po 'troppo complicata per il requisito. Grazie per il tuo aiuto. – Jammerz858

Problemi correlati