2008-12-08 29 views
20

tengo el siguiente código XAML:WPF RichTextBox sin ancho establecido

<Window x:Class="RichText_Wrapping.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1"> 
<Grid> 
    <RichTextBox Height="100" Margin="2" Name="richTextBox1"> 
     <FlowDocument> 
      <Paragraph> 
       This is a RichTextBox - if you don't specify a width, the text appears in a single column 
      </Paragraph> 
     </FlowDocument> 
    </RichTextBox> 
</Grid> 

... Si crea esta ventana en XAML, se puede ver que cuando no se especifica un ancho para la ventana, envuelve el texto en una sola columna, una letra a la vez. ¿Se me escapa algo? Si se trata de una deficiencia conocida en el control, ¿hay alguna solución?

Respuesta

8

Trate de unión a la anchura de la FlowDocument (sólo ida) a la anchura de RichTextBox contenedor.

a mí me funcionó ...

+4

Este problema me sigue sucediendo intermitentemente, así que acabo de derrumbar y llamé a la cuadrícula principal como "mainGrid" y establecí Width = "{Binding ElementName = mainGrid, Path = ActualWidth}" y Height = "{Binding ElementName = mainGrid, Path = ActualHeight} "para forzar el comportamiento que quiero. – Michael

2

Copié su código pegado y no está en una sola columna, ¿tiene un ancho en algún lugar que es pequeño? Tal vez definido en el código detrás, por ejemplo.

+0

De acuerdo. Tiene que haber algo más en juego, tal vez un estilo para uno de sus tipos definidos en su proyecto. El fragmento de XAML que ha publicado se muestra bien en XAML Cruncher, por ejemplo. –

0

Hmm Tengo el mismo problema. Al establecer un ancho en RichEdit se corrigió la columna de 1 letra. Pero cuando no hay ancho establecido, muestra una letra por línea. También configuré el color de fondo como algo muy llamativo, para ver que el control ocupa todo el ancho de la página. (Pero con sólo una columna en el mismo.

Hmmm

20

Este es un error confirmado con el WPF RichTextBox. para solucionarlo, Enlazar el PageWidth de la FlowDocument a la anchura RichTextBox, es decir

<RichTextBox Name="rtb"> 
    <FlowDocument Name="rtbFlowDoc" PageWidth="{Binding ElementName=rtb, Path=ActualWidth}" /> 
</RichTextBox> 

EDITAR: Proporcione un nombre al FlowDocument para que pueda acceder a él en el código subyacente y nunca vuelva a generar el documento de flujo en código subyacente.

+2

¿Dónde se confirmó este error? ¿Hay alguna otra solución alternativa conocida? Desde que construyo mi FlowDocument dinámicamente, el truco de PageWidth no me va a funcionar. – dthrasher

6

El enfoque en this article trabajó para mí:

WPF RichTextBox no proporciona la funcionalidad para ajustar su anchura al texto. Hasta donde yo sé, RichTextBox utiliza un FlowDocumentView en su árbol visual para representar el documento de flujo. Tomará el espacio disponible para representar su contenido, por lo que no ajustará su tamaño al contenido . Como se trata de una clase interna, parece que no podemos anular el proceso de disposición para permitir que un RichTextBox ajuste su tamaño al texto .

Por lo tanto, creo que su enfoque va en la dirección correcta. Desafortunadamente, en base a mi investigación, no hay una forma directa de para medir el tamaño del texto procesado en un RichTextBox.

Hay una solución alternativa que podemos intentar. Podemos recorrer el documento de flujo en RichTextBox recursivamente para recuperar todos los objetos Ejecutar y Párrafo. Luego los convertimos en FormattedText para obtener el tamaño.

This article demuestra cómo convertir un FlowDocument a FormattedText. También escribo una muestra simple usando la clase FlowDocumentExtensions en ese artículo.

public Window2() 
    { 
     InitializeComponent(); 

     StackPanel layoutRoot = new StackPanel(); 
     RichTextBox myRichTextBox = new RichTextBox() { Width=20}; 

     this.Content = layoutRoot; 
     layoutRoot.Children.Add(myRichTextBox); 

     myRichTextBox.Focus(); 
     myRichTextBox.TextChanged += new TextChangedEventHandler((o,e)=>myRichTextBox.Width=myRichTextBox.Document.GetFormattedText().WidthIncludingTrailingWhitespace+20); 
    } 


    public static class FlowDocumentExtensions 
    { 
    private static IEnumerable<TextElement> GetRunsAndParagraphs(FlowDocument doc) 
    { 
     for (TextPointer position = doc.ContentStart; 
     position != null && position.CompareTo(doc.ContentEnd) <= 0; 
     position = position.GetNextContextPosition(LogicalDirection.Forward)) 
     { 
     if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd) 
     { 
      Run run = position.Parent as Run; 

      if (run != null) 
      { 
      yield return run; 
      } 
      else 
      { 
      Paragraph para = position.Parent as Paragraph; 

      if (para != null) 
      { 
       yield return para; 
      } 
      } 
     } 
     } 
    } 

    public static FormattedText GetFormattedText(this FlowDocument doc) 
    { 
     if (doc == null) 
     { 
     throw new ArgumentNullException("doc"); 
     } 

     FormattedText output = new FormattedText(
     GetText(doc), 
     CultureInfo.CurrentCulture, 
     doc.FlowDirection, 
     new Typeface(doc.FontFamily, doc.FontStyle, doc.FontWeight, doc.FontStretch), 
     doc.FontSize, 
     doc.Foreground); 

     int offset = 0; 

     foreach (TextElement el in GetRunsAndParagraphs(doc)) 
     { 
     Run run = el as Run; 

     if (run != null) 
     { 
      int count = run.Text.Length; 

      output.SetFontFamily(run.FontFamily, offset, count); 
      output.SetFontStyle(run.FontStyle, offset, count); 
      output.SetFontWeight(run.FontWeight, offset, count); 
      output.SetFontSize(run.FontSize, offset, count); 
      output.SetForegroundBrush(run.Foreground, offset, count); 
      output.SetFontStretch(run.FontStretch, offset, count); 
      output.SetTextDecorations(run.TextDecorations, offset, count); 

      offset += count; 
     } 
     else 
     { 
      offset += Environment.NewLine.Length; 
     } 
     } 

     return output; 
    } 

    private static string GetText(FlowDocument doc) 
    { 
     StringBuilder sb = new StringBuilder(); 

     foreach (TextElement el in GetRunsAndParagraphs(doc)) 
     { 
     Run run = el as Run; 
     sb.Append(run == null ? Environment.NewLine : run.Text); 
     } 
     return sb.ToString(); 
    } 
    } 
+0

Utilicé 'FormattedTextWidth + 20' para evitar el ajuste. –

0

me di cuenta de que sólo tenía este problema cuando mi estilo por defecto ScrollViewer establece explícitamente HorizontalScrollBarVisibility = Oculto. Al eliminar este setter (el valor predeterminado es Hidden de todos modos) solucioné el problema de una sola columna en mi RichTextBox.

0

Solo para el registro, ya que creo que a este hilo le faltan algunas explicaciones según el por qué: la implementación de RichTextBox MeasureOverride es así. No voy a llamar a eso un error, tal vez solo un comportamiento de diseño pobre justificado por el hecho de que tal como se mencionó anteriormente, el FlowDocument no es barato de medir debido a su complejidad. En pocas palabras, evite la restricción de ancho ilimitada al vincular MinWidth o envolverlo en un contenedor limitante.

/// <summary> 
    /// Measurement override. Implement your size-to-content logic here. 
    /// </summary> 
    /// <param name="constraint"> 
    /// Sizing constraint. 
    /// </param> 
    protected override Size MeasureOverride(Size constraint) 
    { 
     if (constraint.Width == Double.PositiveInfinity) 
     { 
      // If we're sized to infinity, we won't behave the same way TextBox does under 
      // the same conditions. So, we fake it. 
      constraint.Width = this.MinWidth; 
     } 
     return base.MeasureOverride(constraint); 
    } 
+0

Por cierto, recuerde que al buscar en el origen de Framework HELP MUCHO MÁS, comprenderá los comportamientos que pueden no ser tan obvios a primera vista. Vamos, todos sabemos que no existe tal cosa como Bugs ... Es solo características :) jaja. ¡Y felicitaciones a quienquiera en MS que haya hecho que el .NET open source suceda! ¡Haz que nuestra vida sea mucho más fácil! – VeV

Cuestiones relacionadas