I have FixedDocument
page and I want to place TextBlock
on it, but it can be that Textblock
doesn't fit on page by height.
So I want to take lines from generated TextBlock
with TextWrapping
, and then create new TextBlock
, that fitted by height and place it on page.
TextBlock
have LineCount
private property, that mean that it has TextLines
after wrapping and I can somehow get it.
Creating TextBlock
with runs:
public TextItem(PageType pageType, Run[] runs, Typeface typeFace, double fontSize)
: base(pageType)
{
this.TextBlock = new TextBlock();
this.TextBlock.Inlines.AddRange(runs);
if (typeFace != null)
this.TextBlock.FontFamily = typeFace.FontFamily;
if (fontSize > 0)
this.TextBlock.FontSize = fontSize;
this.TextBlock.TextWrapping = TextWrapping.Wrap; //wrapping
}
Creating TextBlock
with text:
public TextItem(PageType pageType, String text, Typeface typeFace, double fontSize)
: base(pageType)
{
if (typeFace == null || fontSize == 0)
throw new Exception("Wrong textitem parameters");
this.TextBlock = new TextBlock();
this.TextBlock.Text = text;
this.TextBlock.FontFamily = typeFace.FontFamily;
this.TextBlock.FontSize = fontSize;
this.TextBlock.TextWrapping = TextWrapping.Wrap;
this.TextBlock.TextAlignment = TextAlignment.Justify;
this.TypeFace = typeFace;
}
Set width to TextBlock
and get DesiredSize
:
this.TextBlock.Width = document.CurrentPage.Content.ActualWidth;
this.TextBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
I faced the exactly same problem, and for some time, I lost the hope and I thought there is no solution for this.
BUT, I was wrong, there are many solutions for that (At least three)
And you are right, one of them use the LineCount
property by using reflection.
And the second using it is own algorithm to get the lines.
And the third, which is preferred to me, has very elegant way to get the result which you want.
Please refer to this question, to see the three answers of this.
Get the lines of the TextBlock according to the TextWrapping property?
public static class TextUtils
{
public static IEnumerable<string> GetLines(this TextBlock source)
{
var text = source.Text;
int offset = 0;
TextPointer lineStart = source.ContentStart.GetPositionAtOffset(1, LogicalDirection.Forward);
do
{
TextPointer lineEnd = lineStart != null ? lineStart.GetLineStartPosition(1) : null;
int length = lineEnd != null ? lineStart.GetOffsetToPosition(lineEnd) : text.Length - offset;
yield return text.Substring(offset, length);
offset += length;
lineStart = lineEnd;
}
while (lineStart != null);
}
}