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
相关产品推荐
相关产品推荐

