2011-04-19 26 views
5

¿Hay alguna manera en WPF de obtener el texto formateado como se muestra en el cuadro de texto cuando TextWrapping = "Wrap"?WPF: Obtener texto "ajustado" de un cuadro de texto

<TextBox Width="200" 
      TextWrapping="Wrap"     
      VerticalScrollBarVisibility="Auto" 
      HorizontalScrollBarVisibility="Auto" /> 

He intentado utilizar TextFormatter clase, pero sóto me permite dibujar el texto en un contexto de dibujo, donde solo me falta el texto con salto de línea incluido.

+0

lo siento, pero no podía entender el problema stat ement. ¿Es que quieres copiar el texto de ese cuadro de texto y, al pegar en otro lugar, deseas conservar las posiciones ajustadas? – publicgk

+0

Como texto o como imagen/visual? –

+0

@publicgk, mi caso exacto es pasar el texto al informe activo mientras se preserva la posición envuelta así que obtuve el mismo ajuste que el que se muestra en la pantalla. Entonces lo necesito como texto. – Fbeauche

Respuesta

3

Aquí se explica cómo obtener el texto completo con saltos de línea aparentes.

Nota:

  • incluyen las siguientes clases de Advanced Text Formatting Example en su proyecto:
    • CustomTextSource
    • FontRendering
    • GenericTextProperties
  • Hay algunas limitaciones que se mencionan en CustomTextSource clase. Sin embargo, creo que sus requisitos no se ven afectados por esas limitaciones.
  • Estos son solo algunos ejemplos. Es posible que desee modificar el código según sus necesidades.
  • El código todavía utiliza un truco (aunque decente) - InputTextBox.ViewportWidth. Es posible que desee probar si el resultado final es exactamente según lo desee.

Ver: Advanced Text Formatting y Advanced Text Formatting Example

Código de ejemplo
XAML:

<Window x:Class="TextFormatterForWrappedText.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBox Width="200" 
      x:Name="InputTextBox" 
      TextWrapping="Wrap" 
      VerticalScrollBarVisibility="Auto" 
      HorizontalScrollBarVisibility="Auto" Margin="23,12,280,241" /> 
     <TextBox x:Name="FormattedDisplayTextBox" Height="172" 
       HorizontalAlignment="Left" VerticalAlignment="Top" 
       Margin="23,105,0,0" Width="438" AcceptsReturn="True" 
       TextWrapping="Wrap" /> 
     <Button HorizontalAlignment="Left" VerticalAlignment="Top" 
       Margin="257,12,0,0" Height="23" Content="Copy" 
       Name="CopyButton" Width="129" Click="CopyButton_Click" /> 
    </Grid> 
</Window> 

Codebehind:

private void CopyButton_Click(object sender, RoutedEventArgs e) 
{ 
    List<string> stringList = GetTextAsStringList(); 
    StringBuilder sb = new StringBuilder(); 
    foreach (string s in stringList) 
    { 
     sb.Append(s); 
     sb.Append("\r\n"); 
    } 

    Clipboard.SetData(System.Windows.DataFormats.Text, sb.ToString()); 

    FormattedDisplayTextBox.Clear(); 
    FormattedDisplayTextBox.Text = sb.ToString(); 
} 

private List<string> GetTextAsStringList() 
{ 
    List<string> stringList = new List<string>(); 
    int pos = 0; 
    string inputText = InputTextBox.Text; 

    CustomTextSource store = new CustomTextSource(); 
    store.Text = inputText; 
    store.FontRendering = new FontRendering(InputTextBox.FontSize, 
              InputTextBox.TextAlignment, 
              null, 
              InputTextBox.Foreground, 
              new Typeface(InputTextBox.FontFamily, 
               InputTextBox.FontStyle, 
               InputTextBox.FontWeight, 
               InputTextBox.FontStretch)); 

    using (TextFormatter formatter = TextFormatter.Create()) 
    { 
     while (pos < store.Text.Length) 
     { 
      using (TextLine line = formatter.FormatLine(store, 
            pos, 
            InputTextBox.ViewportWidth, 
            new GenericTextParagraphProperties(
             store.FontRendering), 
            null)) 
      { 
       stringList.Add(inputText.Substring(pos, line.Length - 1)); 
       pos += line.Length; 
      } 
     } 
    } 

    return stringList; 
} 
+0

Woa, gracias mucho funciona mejor :). Tuve que ajustar un poco el código ya que estaba truncando el último carácter de cada línea, excepto la última. – Fbeauche

+1

¿Podría editar la respuesta con la solución que hizo? –

+0

Los enlaces al "Ejemplo de formato de texto avanzado" están rotos. – Victor

1

Para eso tienes que escribir tu propia lógica haciendo uso de la API de medición de texto.

PASO 1: Bresk el texto del recuadro de entrada en palabras.

PASO 2: Luego mida cada ancho de palabra y combínelos hasta que el ancho de la línea sea menor que el ancho del cuadro de texto.

Consulte esta publicación que explica el proceso de medición de texto. (Social.msdn.microsoft.com/forums/en-US/wpf/thread/...)

+0

Ese no es el punto, él/ella quiere obtener el texto en el formato que TextBlock automáticamente impone en el texto. –

+0

@ H.B. ¡Mi mal! ... Pensé que estaba buscando la manera de manejar el texto de desbordamiento sin usar TextBox. –

+0

@ H.B. Por cierto, Will haciendo el cuadro de texto de solo lectura sería una opción válida en este caso? –

1

Véase la respuesta por Ian Griffiths a esta pregunta: Get Displayed Text from TextBlock

Se pone el texto que se muestra (como se se presenta en la pantalla) desde un TextBlock pero creo que debería poder usarlo también para un TextBox

+0

Buen post allí, pero parece que no funciona bien con un cuadro de texto. Pude obtener el texto mostrado con algunos ajustes, pero no puedo obtener todo el texto en el cuadro de texto ... – Fbeauche

1

Si todo lo que quiere es el texto del cuadro de texto (texto completo y no solo la parte visible), para ser se muestra como texto (con saltos de línea aparentes) en la misma ventana en algún bloque de texto, un truco rápido podría ser:

FormattedText ft = new FormattedText(textBox1.Text, 
    System.Globalization.CultureInfo.CurrentCulture, 
    textBox1.FlowDirection, 
    new Typeface(textBox1.FontFamily, 
     textBox1.FontStyle, 
     textBox1.FontWeight, 
     textBox1.FontStretch), 
    textBox1.FontSize, 
    textBox1.Foreground); 
ft.TextAlignment = textBox1.TextAlignment; 
ft.Trimming = TextTrimming.None; 

ft.MaxTextWidth = textBox1.ViewportWidth; 

textBlock1.Width = textBox1.ViewportWidth; 
textBlock1.Height = ft.Height; 

textBlock1.TextAlignment = textBox1.TextAlignment; 
textBlock1.TextWrapping = textBox1.TextWrapping; 
textBlock1.Text = textBox1.Text; 

Si es necesario en otro lugar, puede llevar los valores a ese lugar y usarlos en el bloque de texto allí.

Si necesita el texto completo (con saltos de línea aparentes) como una lista de cadenas (por ejemplo, List<string>) donde cada elemento representa la línea aparente, necesitará una solución compleja.
Además, si solo necesita la parte visible del texto tal como se muestra en el cuadro de texto, nuevamente se requiere alguna solución compleja.

+0

Necesito el texto completo y no lo estoy usando para mostrarlo en la pantalla :( – Fbeauche

Cuestiones relacionadas