2008-12-08 65 views
20

我有以下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這個窗口中,你可以看到,當你不指定寬度對於窗口來說,它將文本封裝在一個列中,一次一個字母。有什麼我失蹤?如果這是控制中的已知缺陷,是否有任何解決方法?

回答

8

嘗試的FlowDocument的寬度(單程)結合到容器RichTextBox的寬度。

爲我工作...

+4

這個問題不斷髮生在我身上和關閉,所以最終我剛剛崩潰,並命名爲父網格像「mainGrid」,並設置寬度=「{綁定ElementName = mainGrid,路徑= ActualWidth}」和高度=「{綁定元素名稱= mainGrid,Path = ActualHeight}「來強制我想要的行爲。 – Michael 2009-03-04 18:28:14

2

我複製粘貼你的代碼,它不在一個單一的列中,你有一個小的寬度的地方嗎?也許在後面的代碼中定義。

+0

同意。還有其他事情正在進行,或許是你項目中定義的一種類型的風格。例如,您發佈的XAML片段在XAML Cruncher中顯示得很好。 – 2008-12-08 22:15:18

0

嗯我有同樣的問題。在RichEdit上設置寬度固定1個字母的列。但是,如果沒有設置寬度,則每行顯示一個字母。我還將背景顏色設置爲非常華麗,以查看控件佔用頁面的整個寬度。 (但只有一個在其列。

20

這是確認的錯誤與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

6

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

0

我注意到,我只有這個問題時,我的默認的ScrollViewer風格明確設置Horizo​​ntalScrollBarVisibility =隱藏。刪除這個setter(默認值是Hidden)修復了我在RichTextBox中的單列問題。

0

只是爲了記錄,因爲我認爲這個線程是缺少一些解釋,根據爲什麼: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