WPF TextBlock在文本换行后如何获取每行的内容

6

我有一个FixedDocument页面,想在上面放置TextBlock,但是可能由于高度原因,Textblock无法适应页面。
所以我想从生成的具有TextWrappingTextBlock中获取行,并创建新的TextBlock,使其适合高度并放置在页面上。
TextBlock有一个私有属性LineCount,表示它在换行后有TextLines,我可以通过某种方式获取它。
创建带有运行的TextBlock:

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
}

创建带有文本的:
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;
}

TextBlock的宽度设置并获取DesiredSize

this.TextBlock.Width = document.CurrentPage.Content.ActualWidth;
this.TextBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

我知道一种从文本块中获取行的方法,但这仅在控件已经被绘制时才有效。 - Kalyaganov Alexey
你看过WPF的FlowDocument吗?这里有一个链接到msdn - Martin Lottering
是的,但FlowDocument不适合我。我正在尝试手动布局单个A4大小的FixedPage上的元素。这就是为什么如果文本块不适合,我需要将其拆分的原因。 - Kalyaganov Alexey
1个回答

2
我遇到了完全相同的问题,有一段时间我失去了希望,认为这个问题没有解决方案。
但是,我错了,有许多解决方案(至少三种)。
你说得对,其中一种使用反射来使用LineCount属性。
第二种使用自己的算法来获取行数。
第三种方法,对我来说更好,有一种非常优雅的方法来获得想要的结果。
请参考这个问题,查看这三个答案。
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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接