2

My target: a DocumentPaginator which takes a FlowDocument with a table, which splits the table to fit the pagesize and repeat the header/footer (special tagged TableRowGroups) on every page.

For splitting the table I have to know the heights of its rows.

While building the FlowDocument-table by code, the height/width of the TableRows are 0 (of course). If I assign this document to a FlowDocumentScrollViewer (PageSize is set), the heights etc. are calculated. Is this possible without using an UI-bound object? Instantiating a FlowDocumentScrollViewer which is not bound to a window doesn't force the pagination/calculation of the heights.

This is how I determine the height of a TableRow (which works perfectly for documents shown by a FlowDocumentScrollViewer):

        FlowDocument doc = BuildNewDocument();
        // what is the scrollviewer doing with the FlowDocument?
        FlowDocumentScrollViewer dv = new FlowDocumentScrollViewer();
        dv.Document = doc;
        dv.Arrange(new Rect(0, 0, 0, 0));

        TableRowGroup dataRows = null;
        foreach (Block b in doc.Blocks)
        {
          if (b is Table)
          {
            Table t = b as Table;
            foreach (TableRowGroup g in t.RowGroups)
            {
              if ((g.Tag is String) && ((String)g.Tag == "dataRows"))
              {
                dataRows = g;
                break;
              }
            }
          }
          if (dataRows != null)
            break;
        }
        if (dataRows != null)
        {
          foreach (TableRow r in dataRows.Rows)
          {
            double maxCellHeight = 0.0;
            foreach (TableCell c in r.Cells)
            {
              Rect start = c.ElementStart.GetCharacterRect(LogicalDirection.Forward);
              Rect end = c.ElementEnd.GetNextInsertionPosition(LogicalDirection.Backward).GetCharacterRect(LogicalDirection.Forward);
              double cellHeight = end.Bottom - start.Top;
              if (cellHeight > maxCellHeight)
                maxCellHeight = cellHeight;
            }
            System.Diagnostics.Trace.WriteLine("row " + dataRows.Rows.IndexOf(r) + " = " + maxCellHeight);
          }
        }

Edit: I added the FlowDocumentScrollViewer to my example. The call of "Arrange" forces the FlowDocument to calculate its heights etc. I would like to know, what the FlowDocumentScrollViewer is doing with the FlowDocument, so I can do it without the UIElement. Is it possible?

4

1 に答える 1

0

私の推測では、UIElement なしではできません。

FlowDocument 自体は、実際には何もレンダリングしません。refector の型を見ると、単なるデータ型のように見えます。文字列を持っていて、レンダリングされたときにそのサイズを知りたいようなものです...何らかの測定パスを行わないと実際にはできません。

確かなことはわかりませんが、0 ではなくサイズに Double.PositiveInfinity を渡すことで、アレンジ パスのパフォーマンスが向上する可能性があります。少なくとも、「n」個の改行を測定することを心配する必要はありません。

于 2010-04-04T06:03:54.267 に答える