Der Ansatz in this article für mich gearbeitet:
WPF RichTextBox die Funktionalität nicht bieten seine Breite an den Text anzupassen. Soweit ich weiß, verwendet RichTextBox eine FlowDocumentView in seine visuelle Struktur, um das Flowdocument zu rendern. Es wird der verfügbare Speicherplatz benötigt, um seinen Inhalt zu rendern, sodass die Größe nicht an den Inhalt angepasst wird. Da dies eine interne Klasse ist, scheint es, dass wir den Layoutprozess nicht überschreiben können, damit eine RichTextBox ihre Größe an den Text anpassen kann.
Daher denke ich, dass Ihr Ansatz in die richtige Richtung ist. Unglücklicherweise, basierend auf meinen Nachforschungen, gibt es keinen einfachen Weg , um die Größe des gerenderten Textes in einer RichTextBox zu messen.
Es gibt eine Problemumgehung, die wir versuchen können. Wir können das flowdocument in RichTextBox rekursiv durchlaufen, um alle Run- und Paragraph-Objekte abzurufen. Dann konvertieren wir sie in FormattedText, um die Größe zu erhalten.
This article zeigt, wie Sie ein FlowDocument in formatierten Text konvertieren. Ich schreibe auch ein einfaches Beispiel mit der FlowDocumentExtensions-Klasse in diesem Artikel.
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();
}
}
Dieses Problem passiert mit mir immer wieder und wieder, also habe ich das übergeordnete Grid zu etwas wie "mainGrid" gekürzt und benannt und Width = "{Binding ElementName = mainGrid, Path = ActualWidth}" und Height = "{Binding ElementName = mainGrid, Path = ActualHeight} "um das gewünschte Verhalten zu erzwingen. – Michael