WPF DocumentPaginator设置A4横向打印PDF失败及页面尺寸调整问题
问题分析与解决方案
我来帮你拆解下这个问题,分两部分给你针对性的解决方案:
一、A4横向打印失效的原因及修复
你遇到的纵向打印问题,核心是两个细节没处理到位:
1. 忘记设置PrintDialog的打印方向
虽然你手动指定了页面尺寸,但PrintDialog默认是纵向打印模式,打印驱动会直接忽略你的尺寸设置,强制用纵向排版。解决这个很简单,显式把打印票证的方向改成横向就行:
private void InvokePrint(object sender, RoutedEventArgs e) { var dlg = new PrintDialog(); // 关键:设置打印方向为横向 dlg.PrintTicket.PageOrientation = PageOrientation.Landscape; if ((bool)dlg.ShowDialog()) { Size lv_size = new Size(dlg.PrintableAreaWidth, dlg.PrintableAreaHeight); FixedPagePaginator fixedpagepagi = new FixedPagePaginator(scrollv1, lv_size); fixedpagepagi.PageSize = lv_size; dlg.PrintDocument(fixedpagepagi, "Test"); } }
2. FixedPagePaginator的GetPage方法实现有问题
你直接把scrollv1作为DocumentPage的内容,没有用固定页容器来绑定尺寸,导致页面尺寸设置不生效。正确的做法是创建FixedPage作为页面容器,把目标元素放进去,确保容器尺寸和你指定的页面尺寸一致:
public override DocumentPage GetPage(int pageNumber) { // 创建FixedPage作为打印页面的容器 FixedPage fixedPage = new FixedPage(); fixedPage.Width = PageSize.Width; fixedPage.Height = PageSize.Height; // 让目标元素适配页面尺寸 Element.Measure(PageSize); Element.Arrange(new Rect(new Point(0, 0), PageSize)); Element.UpdateLayout(); // 把元素添加到固定页里 fixedPage.Children.Add(Element); // 生成DocumentPage返回 var page = new DocumentPage(fixedPage); return page; }
另外,你当前的PageCount计算只考虑了高度分页,如果你的内容宽度超过横向A4的宽度,可能还要处理横向分页,但如果你的内容本身适配横向尺寸,暂时可以保持现有逻辑。
二、调用受保护的SetSize方法调整DocumentPage尺寸
DocumentPage.SetSize是受保护方法,不能直接调用,我们可以通过继承DocumentPage来封装一个公共方法:
1. 自定义DocumentPage类
public class CustomDocumentPage : DocumentPage { public CustomDocumentPage(Visual visual) : base(visual) { } // 暴露公共方法,内部调用基类的SetSize public void SetPageSize(Size newSize) { base.SetSize(newSize); } }
2. 在分页器中使用自定义类
修改GetPage方法,用我们自定义的CustomDocumentPage来生成页面,并调用SetPageSize显式设置尺寸:
public override DocumentPage GetPage(int pageNumber) { FixedPage fixedPage = new FixedPage(); fixedPage.Width = PageSize.Width; fixedPage.Height = PageSize.Height; Element.Measure(PageSize); Element.Arrange(new Rect(new Point(0, 0), PageSize)); Element.UpdateLayout(); fixedPage.Children.Add(Element); var customPage = new CustomDocumentPage(fixedPage); // 显式设置页面尺寸 customPage.SetPageSize(PageSize); return customPage; }
完整修改后的FixedPagePaginator代码
class FixedPagePaginator : DocumentPaginator { private FrameworkElement Element; private Size Size; public FixedPagePaginator(FrameworkElement element, Size size) { Element = element; Size = size; } public override DocumentPage GetPage(int pageNumber) { FixedPage fixedPage = new FixedPage(); fixedPage.Width = PageSize.Width; fixedPage.Height = PageSize.Height; Element.Measure(PageSize); Element.Arrange(new Rect(new Point(0, 0), PageSize)); Element.UpdateLayout(); fixedPage.Children.Add(Element); var customPage = new CustomDocumentPage(fixedPage); customPage.SetPageSize(PageSize); return customPage; } public override bool IsPageCountValid => true; public int Columns => 1; public int Rows => (int)Math.Ceiling(Element.ActualHeight / PageSize.Height); public override int PageCount => Columns * Rows; public override Size PageSize { get => Size; set { if (!Size.Equals(value)) { Size = value; // 页面尺寸变化时通知分页器更新页面计数 OnPagesChanged(new PagesChangedEventArgs(0, PageCount)); } } } public override IDocumentPaginatorSource Source => null; } public class CustomDocumentPage : DocumentPage { public CustomDocumentPage(Visual visual) : base(visual) { } public void SetPageSize(Size newSize) { base.SetSize(newSize); } }
这样修改后,应该就能正确输出A4横向的PDF文件,同时也实现了通过自定义类调用SetSize方法调整页面尺寸的需求。
内容的提问来源于stack exchange,提问作者user13898537
相关产品推荐
相关产品推荐

