2012-08-22 7 views
10

Wenn Sie nur einen Index und eine Länge (oder einen EndIndex) für einen bestimmten zu wählenden Text erhalten, wie führen Sie dies in der WPF-Version von RichTextBox durch?Auswählen von RichTextBox-Text mit einem Index und einer Länge

Dies ist sehr in Textbox möglich, wie Sie Textbox.Select aufrufen können (startIndex, Länge), aber ich sehe nichts Äquivalentes in RTB.

Edit: Ich habe die Antwort auf Herstellung einer Auswahl

internal string Select(RichTextBox rtb, int index, int length) 
     { 
      TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd); 

      if (textRange.Text.Length >= (index + length)) 
      { 
       TextPointer start = textRange.Start.GetPositionAtOffset(index, LogicalDirection.Forward); 
       TextPointer end = textRange.Start.GetPositionAtOffset(index + length, LogicalDirection.Backward); 
       rtb.Selection.Select(start, end); 
      } 
      return rtb.Selection.Text; 
     } 

jedoch gefunden, wenn ich versuche, um die Linie zu markieren, nachdem die Auswahl getroffen wurde:

rtb.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.LightBlue)); 

Die Hervorhebung Funktion funktioniert nur auf den ersten Versuch und bricht nach dem zweiten Versuch. Weiß jemand den Grund dafür?

Antwort

-1

Verwenden Sie die Select()-Methode auf der RichTextBox.Selection-Eigenschaft.

+0

Die Select-Methode nimmt in zwei Textzeiger und ich habe nur bekam ein Index und eine Länge, mit denen zu arbeiten, die beide ganzzahlig sind. Wie richte ich meine Textpointer-Variablen in diesem Fall richtig ein? – l46kok

-1

Blockquote Sie den Text zwischen den Räumen bekommen .....

private string RichWordOver (RichTextBox rch, int x, int y) {

 int pos = rch.GetCharIndexFromPosition(new Point(x, y)); 
     if (pos <= 0) return ""; 


     string txt = rch.Text; 

     int start_pos; 
     for (start_pos = pos; start_pos >= 0; start_pos--) 
     { 

      char ch = txt[start_pos]; 
      if (!char.IsLetterOrDigit(ch) && !(ch=='_')) break; 
     } 
     start_pos++; 
     int end_pos; 
     for (end_pos = pos; end_pos < txt.Length; end_pos++) 
     { 
      char ch = txt[end_pos]; 
      if (!char.IsLetterOrDigit(ch) && !(ch == '_')) break; 
     } 
     end_pos--; 


     if (start_pos > end_pos) return ""; 
     return txt.Substring(start_pos, end_pos - start_pos + 1); 
    } 

private void rchText_MouseClick (Objektabsender, MouseEventArgs e) { MessageBox.Show (RichWordOver (rchText, eX, eY)); }

4

Ok diese Frage ist alt, aber ich habe endlich die Antwort gefunden, also lege ich das hier.

Ich hatte ähnliche Probleme, als ich versuchte, einige Syntaxhighlighter mit der RichTextBox zu machen. Was ich herausgefunden habe ist, dass wenn Sie mit ApplyPropertyValue arround spielen Sie nicht einfach GetPositionAtOffset mehr verwenden können. Ich glaube, dass die Anwendung von Eigenschaftswerten die "internen Positionen" von TextTokens innerhalb des Dokuments zu verändern scheint, was diese Funktionalität "bremst".

Die Lösung:

Jedesmal, wenn man ClearAllProperties auf den gesamten Textrange des Dokuments mit GetPositionAtOffset ersten Aufruf arbeiten müssen, dann werden alle Ihre Eigenschaften ApplyPropertyValue mit erneut anwenden, aber thistime von rechts nach links . (rechts bedeutet höchsten Offset)

Ich weiß nicht, ob Sie irgendwelche PropertyValues ​​angewendet haben, erwarten Sie die Auswahl Hervorhebung, so dass Sie mehr Gedanken in there setzen müssen.Diese

ist, wie mein Code aussah, wenn es das Problem verursacht:

private void _highlightTokens(FlowDocument document) 
    { 
     TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd); 
     foreach (Token token in _tokenizer.GetTokens(fullRange.Text)) 
     { 
      TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position); 
      TextPointer end = start.GetPositionAtOffset(token.Length); 

      TextRange range = new TextRange(start, end); 
      range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token)); 
     } 
    } 

Und ich regelte es wie folgt aus:

private void _highlightTokens(FlowDocument document) 
    { 
     TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd); 
     fullRange.ClearAllProperties(); // NOTICE: first remove allProperties. 
     foreach (Token token in _tokenizer.GetTokens(fullRange.Text).Reverse()) // NOTICE: Reverse() to make the "right to left" work 
     { 
      TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position); 
      TextPointer end = start.GetPositionAtOffset(token.Length); 

      TextRange range = new TextRange(start, end); 
      range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token)); 
     } 
    } 
Verwandte Themen