WPF - work out width for FlowDocument
I am working in C # and VS2008.
I have a WPF application that contains a FlowDocument that contains a paragraph that contains a few rather short lines (i.e. Spans and LineBreaks). However, the length of the lines changes. I would like the FlowDocument's width to be large enough to accommodate the longest of these lines without wrapping, but not wider so as not to waste space.
Putting it in a grid column with width = Auto doesn't work: FlowDocument always uses the max width allowed, since a FlowDocument can be wrapped to fit several different widths.
I could go through the lines as I generate them in code and work out the width for each one, but I don't see the Width property in the Span or Run classes.
Any ideas on how to automatically or manually set the width for this document?
I used AndrewS 'suggested idea and went from FlowDocument to StackPanel of shortcuts, each containing a string. XAML markup
<Border BorderThickness="2" Margin="2" BorderBrush="Black">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<StackPanel
Orientation="Vertical"
x:Name="itemsStackPanel" />
</ScrollViewer>
</Border>
The code creates spaces and adds them like this:
Label itemLabel = new Label();
// pad left and right, keep close top and bottom
itemLabel.Padding = new Thickness(2,0,2,0);
itemLabel.Content = contentSpan;
this.itemsStackPanel.Children.Add(itemLabel);
The sorting is fine now and the only catch is that the font doesn't look exactly like the FlowDocument next to it, even though the Family and Font Size are the same (Segoe UI, 15pt) and that the Labels look much further than the lines in the FlowDocument. I asked this as a separate question
a source to share
You can replace strings with another type of element, such as TextBlocks or Labels (for which you can control the packaging), or Glyphs, which are "designed to be presented and printed in a fixed format."
I really don't think you want to try measuring the lines and force the width of the document.
a source to share
I have a similar situation, but I want to measure the line width. Unfortunately, RichTextBox has two important features tied together - foreground and background text color in runs and formatting. I want colors and we don't have to worry about formatting. I have a grid of characters and I want to run multiple cursors over the characters. I am planning on implementing background colors as separate cursors and using foreground colors for syntax coloring. This is a fixed width font and I don't want the grid to be wrapped, so there is essentially no formatting. I guess I can implement this as a grid in which I set rows and columns at runtime depending on how big my text is, but this seems like a real waste of resources, especially if the file is really big, i.e.Grid 100x100 with a separate label in each cell. Initially, and perhaps a little naively, I thought it would be binding to a RichTextBox, but I'm starting to believe otherwise. Another possibility is to place the canvas on top of a standard TextBox and draw the rectangles yourself, but deal with everything like scrolls, etc. Sounds ugly and error prone. My code right now:
private static void SetRichText(RichTextBox rtb, string[] arLines)
{
Contract.Assert(arLines.All(l => l.Length == arLines[0].Length));
FlowDocument doc = new FlowDocument { PageWidth = 65535.0 };
IEnumerable<Paragraph> iep = arLines.Select(l =>
{
Paragraph p = new Paragraph();
p.Inlines.Add(new Run(l));
return p;
});
foreach (Paragraph p in iep)
{
doc.Blocks.Add(p);
}
rtb.Document = doc;
doc.PagePadding = new Thickness(0, 0, 0, 0);
Rect rcEOL = rtb.Document.ContentStart.GetPositionAtOffset(arLines[0].Length).GetCharacterRect(LogicalDirection.Forward);
// TODO : Figure why I have to add a fudge factor in the following (I'm guessing some margin I'm unaware of in the
// RichTextBox somewhere)...
rtb.Document.PageWidth = rcEOL.Right + 18;
}
As I state in the comments, it seems to work for my current case, but I haven't tested it with many others, so I'm not sure if it works at all, plus it's just a big kludge anyway that I can't explain so I would like to know how to handle this correctly. Thanks for any answers. Oh, I have to point out, as I said above, that for is a fixed step and all incoming lines are the same length as the contract, so all lines must be the same length.
a source to share