この記事のアプローチは私のために働いた:
WPF RichTextBoxには、テキストに合わせて幅を調整する機能はありません。私の知る限り、RichTextBoxはビジュアルツリーでFlowDocumentViewを使用してFlowdocumentをレンダリングします。コンテンツをレンダリングするために使用可能なスペースが必要になるため、コンテンツに合わせてサイズを調整することはありません。これは内部クラスであるため、レイアウトプロセスをオーバーライドして、RichTextBoxにテキストに合わせてサイズを調整させることはできないようです。
したがって、あなたのアプローチは正しい方向に向かっていると思います。残念ながら、私の調査によれば、RichTextBoxでレンダリングされたテキストのサイズを測定する簡単な方法はありません。
試すことができる回避策があります。RichTextBoxのフロードキュメントを再帰的にループして、すべてのRunオブジェクトとParagraphオブジェクトを取得できます。次に、それらをFormattedTextに変換して、サイズを取得します。
この記事では、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();
}
}