2012-10-25 16 views
10

Mam wieloliniowe pole tekstowe, które wyświetla pewne wartości na podstawie danych, które otrzymuje, (Ogólnie jedna wartość na linię).Jak uzyskać określoną wartość tekstową z pola tekstowego na podstawie pozycji myszy

(W celu wyświetlania wyskakującego okna z niektórymi "alternatywnymi" danymi) chciałabym uzyskać słowo (lub przynajmniej linię), nad którym unosi się mysz, aby można było znaleźć alternatywę do wyświetlenia.

Mam kilka pomysłów, jak to zrobić z obliczeniami opartymi na polu tekstowym i rozmiarach czcionek, ale nie wiem co zrobić w tym kierunku, ponieważ rozmiary i czcionki mogą się często zmieniać.

Więc ... Czy istnieje sposób na wykorzystanie pozycji myszy do pobrania określonego tekstu w polu tekstowym?

Odpowiedz

6

Oto alternatywnym rozwiązaniem. Dodaj zdarzenie MouseMove do swojego obiektu 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

dzięki, to działa doskonale! Podobał mi się regex używany do wyrzucenia białej przestrzeni! :) – Jammerz858

+0

Cieszę się, że ci się podobało. Zwróć uwagę, że nie usuwa po prostu białej spacji. Zachowuje tylko to, co Regex uważa za słowo, więc interpunkcja i wszystko, co nie jest uważane za słowo, zostaje usunięte. –

3

Użyj metody GetCharIndexFromPosition do odwzorowania położenia myszy na indeks w całym tekście. Z tej pozycji postępuj w lewo i w prawo, aż otrzymasz całe słowo.

Aby uzyskać pozycję myszy, należy użyć zdarzenia MouseHover, aby uzyskać je dokładnie wtedy, gdy jest nieruchome, a nie za każdym razem (co spowalniałoby działanie).

+0

Dziękuję. Poszedłem z twoją sugestią, że użyjesz zdarzenia najechania myszką na mousemove i sprawi, że efekt będzie bardziej przyjazny dla użytkownika. Dzięki za pomoc. – Jammerz858

2

Moje rozwiązanie wykorzystuje sztuczkę, aby osiągnąć to, co chcesz.

Po dwukrotnym kliknięciu w obszarze tekstowym wybiera się wyraz podstawowy.

Używanie RichTextBox (TextBox powoduje miganie zdarzeń myszy) w formularzu umożliwia symulowanie dwukrotnego kliknięcia po kliknięciu środkowego przycisku myszy (coś podobnego do słownika Babylon). Jeśli chcesz, możesz również użyć MouseHover zamiast MouseDown. To działa.

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

Całkiem fajne rozwiązanie ... ale trochę zbyt skomplikowane dla wymagań. Dziękuję za pomoc. – Jammerz858