免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1762 | 回复: 0
打印 上一主题 下一主题

[互操作系统] 【Win 10 应用开发】打印UI元素 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-16 09:52 |只看该作者 |倒序浏览
(转)
Windows App支持将UI界面进行打印的功能,这与浏览器中的打印网页的用途相近,其好处就是“所见即所得”,直接把界面上呈现的内容打印下来,比重新创建打印图像方便得多。

要在通用App中实现打印,主要依靠以下几个类型:

PrintManager:位于Windows.Graphics.Printing命名空间,主要负责显示打印对话框,设置打印源等操作。在使用时,首先调用GetForCurrentView静态方法得到一个PrintManager实例;随后处理它的PrintTaskRequested,当要进行打印时就会发生该事件。

PrintTask:表示一个打印任务。在PrintManager对象的PrintTaskRequested事件处理中创建打印任务。

PrintDocument:这个类比较关键(位于Windows.UI.Xaml.Printing命名空间)。通过它可以将UI元素转换为待打印的文档逻辑。a、处理Paginate事件,以计算打印的分页,计算后可以调用PrintDocument.SetPreviewPageCount方法来设置预览页面的总数。b、处理GetPreviewPage事件,当请求预览单个页面时会发生该事件,在处理过程中,可以调用PrintDocument.SetPreviewPage方法来设置要预览的特定页面。c、当开始打印时,会发生AddPages事件,此时调用PrintDocument.AddPage方法向打印文档逻辑添加页面,当所有要打印的页面都添加完毕后,请调用AddPagesComplete方法通知系统可以提交打印了。



当你刚刚接触打印时,你会觉得它好像很复杂,其实,当你动手做过实验后,你就会发现,其实也没什么。我们作为新时代的开发者,应当有迎难而上的精神。

下面咱们来做个例子,把页面上的一个RichTextBlock控件中的内容打印出来。

页面上的XAML大致如下,老周直接贴出来,不作解释了,我相信你能看懂XAML,如果看不懂,那就算了。
  1. <Border Padding="30" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2.         <Grid>
  3.             <Grid.RowDefinitions>
  4.                 <RowDefinition Height="auto"/>
  5.                 <RowDefinition/>
  6.                 <RowDefinition Height="auto"/>
  7.             </Grid.RowDefinitions>
  8.             <StackPanel Margin="0,15" Orientation="Horizontal">
  9.                 <Button Content="开始打印" Click="OnClick"/>
  10.             </StackPanel>
  11.             <RichTextBlock Name="tb" Grid.Row="1" Width="300" >
  12.                 <Paragraph FontSize="36" TextAlignment="Center" FontFamily="楷体">
  13.                     床前明月光,
  14.                     <LineBreak/>
  15.                     疑是地上霜。
  16.                     <LineBreak/>
  17.                     舉頭望明月,
  18.                     <LineBreak/>
  19.                     低頭思故鄉。
  20.                 </Paragraph>
  21.                 <Paragraph TextAlignment="Center">
  22.                     <InlineUIContainer>
  23.                         <Image Height="200" Source="http://img155.poco.cn/mypoco/myphoto/20110305/15/20110305154657_366496406.gif"/>
  24.                     </InlineUIContainer>
  25.                 </Paragraph>
  26.             </RichTextBlock>
  27.             
  28.             ……
  29.         </Grid>
  30.     </Border>
复制代码
咱们这例子要打印的内容,就是那个名为tb的家伙。

进入页面的代码文件,在页面类中声明以下字段:
  1. PrintManager printmgr = PrintManager.GetForCurrentView();
  2.         PrintDocument printDic = null;
  3.         RotateTransform rottrf =null;
  4.         PrintTask task = null;
复制代码
RotateTransform变量的作用是把tb进行旋转变换,这是为了处理打印页面的方向,如果页面是横向,我就把tb转90度。

处理PrintManager的PrintTaskRequested事件,创建打印任务,并设置打印源。
  1. printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
  2.        ……
  3.         private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
  4.         {
  5.             var def = args.Request.GetDeferral();
  6.             // 创建打印任务
  7.             task = args.Request.CreatePrintTask("打印测试", OnPrintTaskSourceRequrested);
  8.             task.Completed += Task_Completed;
  9.             def.Complete();
  10.         }
复制代码
在调用CreatePrintTask方法创建打印任务时,有一个参数需要通过一个委托来设置打印源。所谓打印源,就是我们要打印的文档。
  1. private async void OnPrintTaskSourceRequrested(PrintTaskSourceRequestedArgs args)
  2.         {
  3.             var def = args.GetDeferral();
  4.             await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
  5.                 () =>
  6.                 {
  7.                     // 设置打印源
  8.                     args.SetSource(printDic?.DocumentSource);
  9.                 });
  10.             def.Complete();
  11.         }
复制代码
我们这里要打印的其实就是PrintDocument对象,我们变量命名好像错了,叫printDoc合理一些,我打成了printDic。没事,大家知道就OK了。

下面代码处理按钮的单击事件:
  1. private async void OnClick(object sender, RoutedEventArgs e)
  2.         {
  3.             if (printDic != null)
  4.             {
  5.                 printDic.GetPreviewPage -= OnGetPreviewPage;
  6.                 printDic.Paginate -= PrintDic_Paginate;
  7.                 printDic.AddPages -= PrintDic_AddPages;
  8.             }
  9.             this.printDic = new PrintDocument();
  10.             printDic.GetPreviewPage += OnGetPreviewPage;
  11.             printDic.Paginate += PrintDic_Paginate;
  12.             printDic.AddPages += PrintDic_AddPages;

  13.             // 显示打印对话框
  14.             bool b=await PrintManager.ShowPrintUIAsync();
  15.         }
复制代码
在实例化PrintDocument后,要处理它的几个事件。

先处理AddPages事件,这个事件是在开始执行打印时才会发生,在事件处理中要向打印文档添加页面,每个页面的内容就是我们要打印的UI元素,为了简单,老周只打印一页。
  1. private void PrintDic_AddPages(object sender, AddPagesEventArgs e)
  2.         {
  3.             // 添加要打印的页
  4.             printDic.AddPage(tb);
  5.             // 报告添加完成
  6.             printDic.AddPagesComplete();
  7.         }
复制代码
处理Paginate事件,这个事件在打开打印对话框时发生,并且如果用户调整了打印对话框中的参数后也会发生(比如修改了页面方向),目的是重新计算页面的预览。
  1. private void PrintDic_Paginate(object sender, PaginateEventArgs e)
  2.         {
  3.             PrintTaskOptions opt = task.Options;
  4.             // 根据页面的方向来调整打印内容的旋转方向
  5.             switch (opt.Orientation)
  6.             {
  7.                 case PrintOrientation.Default:
  8.                     rottrf.Angle = 0d;
  9.                     break;
  10.                 case PrintOrientation.Portrait:
  11.                     rottrf.Angle = 0d;
  12.                     break;
  13.                 case PrintOrientation.Landscape:
  14.                     rottrf.Angle = 90d;
  15.                     break;
  16.             }

  17.             // 设置预览页面的总页数
  18.             printDic.SetPreviewPageCount(1, PreviewPageCountType.Final);
  19.         }
复制代码
下面代码添加特定页面的预览。
  1. private void OnGetPreviewPage(object sender, GetPreviewPageEventArgs e)
  2.         {
  3.             // 设置要预览的页面
  4.             printDic.SetPreviewPage(e.PageNumber, this.tb);
  5.         }
复制代码
大家要注意,页面预览和实际打印是两回事,因此SetPreviewPage只是设置要预览的UI元素,而实际打印是要在AddPages事件中通过AddPage方法来添加页面。



当示例完成之时,大家可能又遇到问题了,我没有打印机,怎么办? 没事,老周很穷,也没有打印机,但不要忘记,系统里面有这些功能:

是啊,有它们就行,搜索“设备与打印机”就能找到它们,所以在运行示例后,直接把内容打印为.pdf文档就可以了,打印完后,.pdf文件存到“文档”目录中。



现在运行应用程序,然后点击“开始打印”按钮。

然后会弹出打印对话框。

确认开始打印,点击“打印”按钮。打印完成后系统会以Toast通知来提醒你。下图所示是打印出来的.pdf文件。

好了,是不是有点高大上的感觉呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP