WPF控件转PDF丢失样式求助:文本居中设置失效
WPF控件转PDF丢失文本居中样式的解决办法
我看你现在遇到的问题是把WPF窗口里的控件转成PDF后,原本居中的TextBlock变成左对齐了对吧?这主要是因为你在手动构建FixedPage时,没有给它设置正确的尺寸和布局上下文,导致控件的对齐属性找不到参照容器。我帮你调整下代码,完美解决这个问题:
问题根源分析
你原来的代码直接把Grid里的TextBlock移到了空的FixedPage中,但这个FixedPage既没有设置和原窗口一致的尺寸,也没有执行完整的布局流程(Measure/Arrange/UpdateLayout)。HorizontalAlignment="Center"是相对于父容器的宽度生效的,没有父容器的尺寸约束,文本自然就默认左对齐了。
方案一:克隆控件并完善FixedPage布局
这种方式会保留原窗口的控件状态,同时确保PDF里的布局和WPF窗口完全一致:
private void button_Click(object sender, RoutedEventArgs e) { btn.Visibility = Visibility.Collapsed; this.UpdateLayout(); // 确保当前窗口布局已更新 // 创建FixedDocument和页面内容 FixedDocument fixedDoc = new FixedDocument(); PageContent pageContent = new PageContent(); FixedPage fixedPage = new FixedPage(); // 给FixedPage设置和原窗口完全一致的尺寸 fixedPage.Width = this.Width; fixedPage.Height = this.Height; // 克隆原Grid的内容(避免直接移除原窗口控件,破坏界面状态) Grid originalGrid = this.Content as Grid; Grid gridCopy = new Grid(); foreach (UIElement child in originalGrid.Children) { if (!(child is Button)) // 排除转换按钮,不让它出现在PDF里 { UIElement clonedChild = CloneUIElement(child); gridCopy.Children.Add(clonedChild); } } // 将克隆的Grid添加到FixedPage并执行布局流程 fixedPage.Children.Add(gridCopy); fixedPage.Measure(new Size(this.Width, this.Height)); fixedPage.Arrange(new Rect(0, 0, this.Width, this.Height)); fixedPage.UpdateLayout(); ((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage); fixedDoc.Pages.Add(pageContent); // 写入XPS文件再转换为PDF string tempFilename = "temp.xps"; if (File.Exists(tempFilename)) File.Delete(tempFilename); using (XpsDocument xpsd = new XpsDocument(tempFilename, FileAccess.ReadWrite)) { XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd); xw.Write(fixedDoc); } PdfSharp.Xps.XpsConverter.Convert(tempFilename, "D:/testing.pdf", 1); Process.Start("D:/testing.pdf"); btn.Visibility = Visibility.Visible; } // 辅助方法:克隆UIElement,保留原控件的所有样式属性 private UIElement CloneUIElement(UIElement element) { string xaml = XamlWriter.Save(element); return XamlReader.Parse(xaml) as UIElement; }
方案二:直接使用PrintVisual打印(更简洁)
如果你不需要手动调整FixedDocument的内容,直接用PrintVisual打印整个窗口的可视内容是最省心的方式,所有样式都会完整保留:
private void button_Click(object sender, RoutedEventArgs e) { btn.Visibility = Visibility.Collapsed; this.UpdateLayout(); // 确保布局生效 string tempFilename = "temp.xps"; if (File.Exists(tempFilename)) File.Delete(tempFilename); // 配置打印对话框,输出到XPS文件 PrintDialog printDlg = new PrintDialog(); printDlg.PrintQueue = new PrintQueue(new PrintServer(), "Microsoft XPS Document Writer"); printDlg.PrintTicket.PageMediaSize = new PageMediaSize(PageMediaSizeName.Custom, this.Width, this.Height); printDlg.PrintFileName = tempFilename; // 打印当前窗口的可视内容 if (printDlg.PrintVisual(this, "WPF to PDF")) { PdfSharp.Xps.XpsConverter.Convert(tempFilename, "D:/testing.pdf", 1); Process.Start("D:/testing.pdf"); } btn.Visibility = Visibility.Visible; }
这两种方法都能完美解决文本居中丢失的问题,你可以根据自己的需求选择。方案一更灵活,适合需要修改PDF内容的场景;方案二更简洁,适合直接转整个窗口的场景。
内容的提问来源于stack exchange,提问作者Shivam Manandhar
相关产品推荐
相关产品推荐

