6

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));
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Kalyaganov Alexey
  • 1,701
  • 1
  • 16
  • 23
  • http://pastebin.com/b6cZD5pp I know one way to get lines from textblock, but this only work when control was already drawned. – Kalyaganov Alexey Jan 16 '13 at 10:52
  • Have you looked at the wpf `FlowDocument`? A link to [msdn](http://msdn.microsoft.com/en-us/magazine/cc163371.aspx). – Martin Lottering Jan 16 '13 at 10:55
  • Yes, but FlowDocument does not suitable for me. I`m try layout elements manual on single FixedPage, that have A4 size. That`s why i need to split textblock if it does not fit. – Kalyaganov Alexey Jan 16 '13 at 12:52

1 Answers1

2

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?


Here is a copy of the best solution (in my opinion)
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);
    }
}
Community
  • 1
  • 1
Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131