You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中FlowDocument集成Table报错及页面显示问题求助

WPF中在FlowDocument第一页集成Table的解决方案

问题根源

你遇到的错误是因为Grid是UIElement容器,仅接受UIElement类型的子元素,而System.Windows.Documents.Table属于FlowDocument的Block元素,并非UIElement,所以无法直接添加到Grid的行中;之前尝试的BlockUIContainer用法错误——它的作用是将UIElement包装成Block元素加入FlowDocument,而非反过来包装Block元素。

解决方案一:将Grid和Table作为FlowDocument的同级Block元素(推荐)

这种方式利用FlowDocument的原生排版能力,让Grid(包装后)和Table自然排列在同一页,只要空间足够就会显示在第一页。

代码示例

private void Print_Click(object sender, RoutedEventArgs e)
{
    // 初始化FlowDocument和Section
    FlowDocument printDoc = new FlowDocument();
    Section mainSection = new Section();
    printDoc.Blocks.Add(mainSection);

    // 创建并配置现有Grid
    Grid contentGrid = new Grid();
    // 添加原有3行定义
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    // 向Grid中添加原有UI元素(示例)
    contentGrid.Children.Add(new TextBlock { Text = "第一行内容", Margin = new Thickness(5) });
    Grid.SetRow(contentGrid.Children[0], 0);
    contentGrid.Children.Add(new TextBlock { Text = "第二行内容", Margin = new Thickness(5) });
    Grid.SetRow(contentGrid.Children[1], 1);
    contentGrid.Children.Add(new TextBlock { Text = "第三行内容", Margin = new Thickness(5) });
    Grid.SetRow(contentGrid.Children[2], 2);

    // 将Grid包装为BlockUIContainer,加入Section
    mainSection.Blocks.Add(new BlockUIContainer(contentGrid));

    // 创建并配置Table
    Table dataTable = new Table { CellSpacing = 0 };
    // 添加列定义
    dataTable.Columns.Add(new TableColumn { Width = new GridLength(120) });
    dataTable.Columns.Add(new TableColumn { Width = new GridLength(200) });
    // 创建行组
    TableRowGroup rowGroup = new TableRowGroup();
    // 表头行
    TableRow headerRow = new TableRow();
    headerRow.Cells.Add(new TableCell(new Paragraph(new Run("序号"))) { Padding = new Thickness(5) });
    headerRow.Cells.Add(new TableCell(new Paragraph(new Run("内容"))) { Padding = new Thickness(5) });
    rowGroup.Rows.Add(headerRow);
    // 数据行
    TableRow dataRow = new TableRow();
    dataRow.Cells.Add(new TableCell(new Paragraph(new Run("1"))) { Padding = new Thickness(5) });
    dataRow.Cells.Add(new TableCell(new Paragraph(new Run("测试数据"))) { Padding = new Thickness(5) });
    rowGroup.Rows.Add(dataRow);
    dataTable.RowGroups.Add(rowGroup);

    // 将Table直接加入Section(Table本身是Block类型,无需包装)
    mainSection.Blocks.Add(dataTable);

    // 执行打印
    PrintDialog printDialog = new PrintDialog();
    if (printDialog.ShowDialog() == true)
    {
        printDialog.PrintDocument(((IDocumentPaginatorSource)printDoc).DocumentPaginator, "带表格的打印文档");
    }
}

解决方案二:将Table包装为UIElement放入Grid行

如果必须把Table放在Grid的第4行内,需要将Table放入一个FlowDocument容器控件(如FlowDocumentScrollViewer),将其作为UIElement加入Grid:

代码示例

private void Print_Click(object sender, RoutedEventArgs e)
{
    // 初始化FlowDocument和BlockUIContainer承载Grid
    FlowDocument printDoc = new FlowDocument();
    Grid contentGrid = new Grid();
    // 添加4行定义
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    contentGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

    // 向Grid前3行添加原有内容...

    // 创建Table
    Table dataTable = new Table { CellSpacing = 0 };
    // 配置Table列和行(同方案一)...

    // 将Table放入FlowDocument,再包装为FlowDocumentScrollViewer(UIElement)
    FlowDocument tableDoc = new FlowDocument(dataTable);
    FlowDocumentScrollViewer tableViewer = new FlowDocumentScrollViewer
    {
        Document = tableDoc,
        HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
        VerticalScrollBarVisibility = ScrollBarVisibility.Hidden,
        Margin = new Thickness(5)
    };

    // 将tableViewer加入Grid第4行
    Grid.SetRow(tableViewer, 3);
    contentGrid.Children.Add(tableViewer);

    // 将Grid加入FlowDocument
    printDoc.Blocks.Add(new BlockUIContainer(contentGrid));

    // 执行打印
    PrintDialog printDialog = new PrintDialog();
    if (printDialog.ShowDialog() == true)
    {
        printDialog.PrintDocument(((IDocumentPaginatorSource)printDoc).DocumentPaginator, "Grid内嵌表格的打印文档");
    }
}

关键说明

  • 方案一利用FlowDocument的流式排版,Grid和Table会自动按顺序填充页面,排版更自然,适合打印场景。
  • 方案二适合必须保持Grid布局结构的场景,但Table的排版会受限于容器控件的尺寸。

内容的提问来源于stack exchange,提问作者trycatch-21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:14:58