2008-11-20 20 views
6

Si una línea de texto se ajusta a una línea adicional, ¿cómo determino programáticamente el punto en la cadena donde se rompió?WPF richTextBox pregunta

Ejemplo: Input string = "Esta es una prueba de una línea de texto envuelta".

 Based on the width of the richTextBox it could display: 


      This is a test of a wrapped line of 
      text. 

Lo que necesito determinar es el desplazamiento en la línea de la (s) palabra (s) que se ajustaron. En el caso anterior, la palabra "texto".

Cuando extraigo el Xaml de richTextBox, obtengo el texto original sin empaquetar.

Gracias,

Bob Kerlinger

+0

¿Qué está tratando de utilizar este desplazamiento para? –

+0

Necesito extraer el texto compuesto tal como se muestra para que pueda volver a mostrarlo exactamente como fue compuesto en otro medio. Además, en algunos casos, necesito crear una sangría que richTextBox no admita. También tengo que hacer algún otro formato especial. –

Respuesta

2

El truco que encontré utiliza la clase TextPointer y su método GetCharacterRec.

RichTextBox contiene un FlowDocument. El texto en documentos de flujo está contenido en un objeto Ejecutar (algo simplificado, pero funciona). El código encuentra el TextPointer al comienzo de la primera ejecución. Luego obtiene el rectángulo delimitador de ese primer personaje. A continuación, el código avanza un carácter a la vez, obtiene un nuevo rectángulo delimitador y comprueba si la parte inferior del nuevo rectángulo es diferente del rectángulo original. Si el fondo es diferente, entonces estamos en una nueva línea. TextPointer puede obtener el texto antes o después del descanso.

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
    } 

    private void inspect(object sender, RoutedEventArgs e) 
    { 
     TextPointer pointer = FindRun(inBox.Document); 

     string textAfterBreak = FindBreak(pointer); 

     outBox.Text = textAfterBreak; 
    } 

    private string FindBreak(TextPointer pointer) 
    { 
     Rect rectAtStart = pointer.GetCharacterRect(LogicalDirection.Forward); 

     pointer = pointer.GetNextInsertionPosition(LogicalDirection.Forward); 
     Rect currentRect = pointer.GetCharacterRect(LogicalDirection.Forward); 

     while (currentRect.Bottom == rectAtStart.Bottom) 
     { 
      pointer = pointer.GetNextInsertionPosition(LogicalDirection.Forward); 
      currentRect = pointer.GetCharacterRect(LogicalDirection.Forward); 
     } 

     string textBeforeBreak = pointer.GetTextInRun(LogicalDirection.Backward); 
     string textAfterBreak = pointer.GetTextInRun(LogicalDirection.Forward); 

     return textAfterBreak; 
    } 

    private TextPointer FindRun(FlowDocument document) 
    { 
     TextPointer position = document.ContentStart; 

     while (position != null) 
     { 
      if (position.Parent is Run) 
       break; 

      position = position.GetNextContextPosition(LogicalDirection.Forward); 
     } 

     return position; 
    } 
} 

<Window x:Class="LineBreaker.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
     </Grid.RowDefinitions> 
     <RichTextBox Grid.Row="0" Name="inBox"> 
     </RichTextBox> 
     <Button Grid.Row="1" Click="inspect">Find Break</Button> 
     <TextBox Name="outBox" Grid.Row="2"/> 
    </Grid> 
</Window> 
1

http://msdn.microsoft.com/en-us/library/system.windows.documents.textpointer.getlinestartposition.aspx

TextPointer startOfFirstLine = richTextBox.Document.ContentStart; 
TextPointer startOfNextLine = startOfFirstLine.GetLineStartPosition(1); 
if(startOfNextLine != null) 
{ 
    // At this point what you do with the TextPointer depends on what you define as the position of text. 
    // If you want to find out how many characters are on the first line ... 
    int firstLineCharacterCount = new TextRange(startOfFirstLine, startOfNextLine).Text.Length; 
} 
+0

Lo intenté al principio, pero el startOfNexLine siguió devolviendo nulo. Parece encontrar la posición de inicio de la siguiente ejecución, pero no encontrará saltos dentro de un objeto de ejecución. Me podría estar perdiendo algo. –

+0

Sé que llegué un poco tarde a la fiesta, pero ¿descubrió una forma de evitar que startOfNextLine devuelva nulo? – JessMcintosh

1

Pero startOfFirstLine.GetLineStartPosition(1) vuelve nulos

Cuestiones relacionadas