WPF FlowDocument: принудительное вычисление высоты и т. Д. «Вне экрана» - PullRequest
2 голосов
/ 04 января 2010

Моя цель: DocumentPaginator, который принимает FlowDocument с таблицей, которая разбивает таблицу по размеру страницы и повторяет верхний / нижний колонтитулы (специальные теговые TableRowGroups) на каждой странице.

Для разбиения таблицы я должен знать высоту ее рядов.

При построении таблицы FlowDocument по коду высота / ширина TableRows равны 0 (конечно). Если я назначу этот документ для FlowDocumentScrollViewer (установлен PageSize), высоты и т. Д. Рассчитываются. Возможно ли это без использования объекта, связанного с пользовательским интерфейсом? Создание экземпляра FlowDocumentScrollViewer, который не привязан к окну, не вызывает разбиение на страницы / расчет высот.

Вот как я определяю высоту TableRow (которая отлично работает для документов, отображаемых 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: Я добавил FlowDocumentScrollViewer в мой пример. Вызов «Arrange» заставляет FlowDocument вычислять его высоту и т. Д. Я хотел бы знать, что FlowDocumentScrollViewer делает с FlowDocument, поэтому я могу сделать это без UIElement. Возможно ли это?

1 Ответ

0 голосов
/ 04 апреля 2010

Я думаю, что нет, вы не можете сделать это без UIElement.

FlowDocument сам по себе ничего не отображает. Глядя на тип в Relector, он выглядит так, как будто это просто тип данных. Это все равно что иметь строку и хотеть узнать ее размер при рендеринге ... на самом деле не могу сделать это без выполнения какого-то прохода меры.

Я точно не знаю, но вы могли бы получить лучшую производительность на этапе аранжировки, передав Double.PositiveInfinity для размера, а не 0. По крайней мере, тогда вам не придется беспокоиться об измерении строки 'n' брейки.

...