WPF RichTextBox的,没有宽度为

WPF RichTextBox的,没有宽度为

问题描述:

我有以下XAML代码:WPF RichTextBox的,没有宽度为

<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> 

...如果你创建XAML这个窗口中,你可以看到,当你不指定宽度对于窗口来说,它将文本封装在一个列中,一次一个字母。有什么我失踪?如果这是控制中的已知缺陷,是否有任何解决方法?

尝试的FlowDocument的宽度(单程)结合到容器RichTextBox的宽度。

为我工作...

+4

这个问题不断发生在我身上和关闭,所以最终我刚刚崩溃,并命名为父网格像“mainGrid”,并设置宽度=“{绑定ElementName = mainGrid,路径= ActualWidth}”和高度=“{绑定元素名称= mainGrid,Path = ActualHeight}“来强制我想要的行为。 – Michael 2009-03-04 18:28:14

我复制粘贴你的代码,它不在一个单一的列中,你有一个小的宽度的地方吗?也许在后面的代码中定义。

+0

同意。还有其他事情正在进行,或许是你项目中定义的一种类型的风格。例如,您发布的XAML片段在XAML Cruncher中显示得很好。 – 2008-12-08 22:15:18

嗯我有同样的问题。在RichEdit上设置宽度固定1个字母的列。但是,如果没有设置宽度,则每行显示一个字母。我还将背景颜色设置为非常华丽,以查看控件占用页面的整个宽度。 (但只有一个在其列。

这是确认的错误与WPF的RichTextBox。为了解决这个问题,绑定的FlowDocument的页宽以在RichTextBox宽度,即

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

编辑: 给FlowDocument一个名称,以便您可以在后面的代码中访问它,并且不会在代码隐藏中新建流文档。

+2

这个错误在哪里得到证实?有没有其他已知的解决方法?由于我动态构建了FlowDocument,因此PageWidth技巧不适用于我。 – dthrasher 2010-06-23 22:23:42

this article的方法为我工作:

WPF RichTextBox中没有提供的功能,以它的宽度 调整到文本。据我所知,RichTextBox在其可视化树中使用 中的FlowDocumentView来呈现Flowdocument。它将采用可用的 空间来呈现其内容,因此它不会将其大小调整为 内容。由于这是一个内部类,因此我们似乎无法覆盖 布局过程,让RichTextBox将其大小调整为 文本。

因此,我认为你的方法是在正确的方向。 不幸的是,基于我的研究,没有简单的方法来测量RichTextBox中呈现的文本的大小 。

有一种解决方法,我们可以尝试。我们可以循环遍历RichTextBox中的flowdocument 以检索所有Run和Paragraph对象。 然后我们将它们转换成FormattedText以获得大小。

This article演示如何将FlowDocument转换为 FormattedText。我还使用该文章中的 FlowDocumentExtensions类编写了一个简单示例。

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

我用`FormattedTextWidth + 20`来防止包装。 – 2017-09-11 21:58:34

我注意到,我只有这个问题时,我的默认的ScrollViewer风格明确设置Horizo​​ntalScrollBarVisibility =隐藏。删除这个setter(默认值是Hidden)修复了我在RichTextBox中的单列问题。

只是为了记录,因为我认为这个线程是缺少一些解释,根据为什么:RichTextBox MeasureOverride实现是这样的。我不会说这是一个错误,也许只是一个糟糕的设计行为,正如上面提到的FlowDocument由于其复杂性而不便宜。底线,通过绑定MinWidth避免无限宽度约束或将其包裹在限制容器中。

/// <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

顺便说一句,请记住,像A LOT一样查看框架帮助的来源,以了解可能一见钟情并不那么明显的行为。来吧,我们都知道有没有这样的想法作为臭虫...这只是功能:)大声笑。并且感谢MS开发.NET开源的任何人!让我们的生活变得如此简单! – VeV 2017-02-14 09:13:07