原文:https://www.cnblogs.com/jiajiayuan/archive/2012/04/13/2444246.html

Silverlight中的打印只有一个类,那就是PrintDocment这个对象来实现。
下面我用两种方法来实现Silverlight的打印:
第一种:

  1. private void btnPrint_Click(object sender, RoutedEventArgs e)
  2. {
  3. PrintDocument document = new PrintDocument();
  4.  
  5. // tell the API what to print
  6. document.PrintPage += (s, args) =>
  7. {
  8. args.PageVisual = GPrint;
  9. };
  10.  
  11. // call the Print() with a proper name which will be visible in the Print Queue
  12. document.Print("Silverlight Print Application Demo");
  13. }

第二种:
实现方式也很简单,其实只需两个步骤即可完成,即绑定PrintDocument的PrintPage事件和调用Print方法。

  1. PrintDocument document = new PrintDocument();
  2. document.PrintPage += documentImage_PrintPage;
  3. document.Print("Image Document");

这个就完成了一个打印,其中PrintPage事件是最为重要的,因为整个打印的工作都是在这个事件中完成的,另外该事件的参数 PrintPageEventArgs构成了整个打印过程中的属性的设置;Print方法需要传递一个参数,参数为打印的文件的名称,在调用该方法的时候 开始触发一系列的打印事件。
PrintPageEventArgs类型的属性:
PrintableArea:获取一个Size类型的值,表示打印的范围,分别表示Height和Width,如果打印的部分超出了区域,则被截取。
PageMargins:获取打印页的Margin值。
PageVisual:设置要打印的对象,可以是一个TextBlock、Image,也可以是一个复杂的元素(Grid或者Canvas)。
HasMorePages:一个bool值,标识是否多页。
一个简单的例子:

  1. private void btnPrintImage_Click(object sender, RoutedEventArgs e)
  2. {
  3. PrintDocument document = new PrintDocument();
  4. document.PrintPage += new EventHandler<PrintPageEventArgs>(document_PrintPage);
  5. document.Print("Print Image");
  6. }
  7.  
  8. void document_PrintPage(object sender, PrintPageEventArgs e)
  9. {
  10. Image imagePrint = new Image();
  11. imagePrint.Source = img.Source;
  12. imagePrint.Height = e.PrintableArea.Height;
  13. imagePrint.Width = e.PrintableArea.Width;
  14. e.PageVisual = imagePrint;
  15. e.HasMorePages = false;
  16. }

分页打印的例子:

  1. //当前打印的行的索引,用于遍历ListBox.Items
  2. private int listPrintIndex;
  3. private void btnPrintList_Click(object sender, RoutedEventArgs e)
  4. {
  5. //初始值为0
  6. listPrintIndex = 0;
  7. PrintDocument document = new PrintDocument();
  8. document.PrintPage += new EventHandler<PrintPageEventArgs>(document_PrintPage);
  9. document.Print("Print List");
  10. }
  11.  
  12. //设置每一项之间的间距
  13. private int extraMargin = 50;
  14. void document_PrintPage(object sender, PrintPageEventArgs e)
  15. {
  16. //定义一个打印的元素
  17. Canvas printSurface = new Canvas();
  18. e.PageVisual = printSurface;
  19. //得到最顶端位置
  20. double topPosition = e.PageMargins.Top + extraMargin;
  21.  
  22. //遍历当前的ListBox.Items
  23. while (listPrintIndex<lstPrint.Items.Count)
  24. {
  25. //实例化TextBlock用来存放ListItem的值
  26. TextBlock txt = new TextBlock();
  27. txt.FontSize = 30;
  28. //得到ListBox每一项的值
  29. txt.Text = lstPrint.Items[listPrintIndex].ToString();
  30. double measuredHeight = txt.ActualHeight;
  31. //如果打印的当前行高度不合适的话,则进行分页
  32. if (measuredHeight>(e.PrintableArea.Height- topPosition- extraMargin))
  33. {
  34. e.HasMorePages = true;
  35. return ;
  36. }
  37.  
  38. //设置TextBlock在Canvas中的位置
  39. txt.SetValue(Canvas.TopProperty, topPosition);
  40. txt.SetValue(Canvas.LeftProperty, e.PageMargins.Left + extraMargin);
  41. //将TextBlock添加到打印的元素中去
  42. printSurface.Children.Add(txt);
  43.  
  44. listPrintIndex++;
  45. //追加高度
  46. topPosition = topPosition + measuredHeight;
  47. }
  48. e.HasMorePages = false;
  49. }

有时我们会发现打印的图片并不完整,这样就需要一个类:

  1. public static class Extensions
  2. {
  3. public static void Print(this FrameworkElement element,
  4. string Document, HorizontalAlignment HorizontalAlignment,
  5. VerticalAlignment VerticalAlignment, Thickness PageMargin,
  6. bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete)
  7. {
  8. Print(new List<FrameworkElement>() { element }, Document,
  9. HorizontalAlignment, VerticalAlignment, PageMargin,
  10. PrintLandscape, ShrinkToFit, OnPrintComplete);
  11. }
  12.  
  13. public static void Print<T>(this List<T> elements,
  14. string Document, HorizontalAlignment HorizontalAlignment,
  15. VerticalAlignment VerticalAlignment, Thickness PageMargin,
  16. bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete)
  17. {
  18. PrintDocument printDocument = new PrintDocument();
  19. PageMargin = PageMargin == null ? new Thickness(10) : PageMargin;
  20. Document = (string.IsNullOrEmpty(Document)) ? "Print Document" : Document;
  21. int currentItemIndex = 0;
  22. printDocument.PrintPage += (s, e) =>
  23. {
  24. if (!typeof(FrameworkElement).IsAssignableFrom(elements[currentItemIndex].GetType()))
  25. {
  26. throw new Exception("Element must be an " +"object inheriting from FrameworkElement");
  27. }
  28.  
  29. FrameworkElement element = elements[currentItemIndex] as FrameworkElement;
  30.  
  31. if (element.Parent == null || element.ActualWidth == double.NaN ||element.ActualHeight == double.NaN)
  32. {
  33. throw new Exception("Element must be rendered, " +
  34. "and must have a parent in order to print.");
  35. }
  36.  
  37. TransformGroup transformGroup = new TransformGroup();
  38.  
  39. //First move to middle of page... 首先移动到页面的中间
  40. transformGroup.Children.Add(new TranslateTransform() //TranslateTransform偏移动画
  41. {
  42. X = (e.PrintableArea.Width - element.ActualWidth) / 2,
  43. Y = (e.PrintableArea.Height - element.ActualHeight) / 8
  44. });
  45. double scale = 1;
  46. if (PrintLandscape) //如果打印空白 需要旋转
  47. {
  48. //Then, rotate around the center 然后旋转到中心
  49. transformGroup.Children.Add(new RotateTransform()
  50. {
  51. Angle = 90,
  52. CenterX = e.PrintableArea.Width / 2,
  53. CenterY = e.PrintableArea.Height / 2
  54. });
  55.  
  56. if (ShrinkToFit) //如果自适应大小
  57. {
  58. if ((element.ActualWidth + PageMargin.Left +PageMargin.Right) > e.PrintableArea.Height) //如果宽度大于纸张的高度
  59. {
  60. //Math.Round 方法 将值舍入到最接近的整数或指定的小数位数。
  61. scale = Math.Round(e.PrintableArea.Height /(element.ActualWidth + PageMargin.Left + PageMargin.Right), 2);
  62. }
  63. if ((element.ActualHeight + PageMargin.Top + PageMargin.Bottom) > e.PrintableArea.Width) //如果高度大于纸张的宽度
  64. {
  65. double scale2 = Math.Round(e.PrintableArea.Width /(element.ActualHeight + PageMargin.Top + PageMargin.Bottom), 2);
  66. scale = (scale2 < scale) ? scale2 : scale;
  67. }
  68. }
  69. }
  70. else if (ShrinkToFit) //如果不打印空白并自适应大小 不需要旋转
  71. {
  72. //Scale down to fit the page + margin
  73. if ((element.ActualWidth + PageMargin.Left + PageMargin.Right) > e.PrintableArea.Width) //如果宽度大于纸张的宽度
  74. {
  75. scale = Math.Round(e.PrintableArea.Width /(element.ActualWidth + PageMargin.Left + PageMargin.Right), 2);
  76. }
  77. if ((element.ActualHeight + PageMargin.Top + PageMargin.Bottom) > e.PrintableArea.Height) //如果高度大于纸张的高度
  78. {
  79. double scale2 = Math.Round(e.PrintableArea.Height /(element.ActualHeight + PageMargin.Top + PageMargin.Bottom), 2);
  80. scale = (scale2 < scale) ? scale2 : scale;
  81. }
  82. }
  83.  
  84. //Scale down to fit the page + margin
  85. if (scale != 1)
  86. {
  87. transformGroup.Children.Add(new ScaleTransform() //ScaleTransform缩放动画
  88. {
  89. ScaleX = scale,
  90. ScaleY = scale,
  91. CenterX = e.PrintableArea.Width / 2,
  92. CenterY = e.PrintableArea.Height / 2
  93. });
  94. }
  95.  
  96. if (VerticalAlignment == VerticalAlignment.Top)
  97. {
  98. //Now move to Top
  99. if (PrintLandscape)
  100. {
  101. transformGroup.Children.Add(new TranslateTransform()
  102. {
  103. X = 0,
  104. Y = PageMargin.Top - (e.PrintableArea.Height -(element.ActualWidth * scale)) / 2
  105. });
  106. }
  107. else
  108. {
  109. transformGroup.Children.Add(new TranslateTransform()
  110. {
  111. X = 0,
  112. Y = PageMargin.Top - (e.PrintableArea.Height -(element.ActualHeight * scale)) / 2
  113. });
  114. }
  115. }
  116. else if (VerticalAlignment == VerticalAlignment.Bottom)
  117. {
  118. //Now move to Bottom
  119. if (PrintLandscape)
  120. {
  121. transformGroup.Children.Add(new TranslateTransform()
  122. {
  123. X = 0,
  124. Y = ((e.PrintableArea.Height -(element.ActualWidth * scale)) / 2) - PageMargin.Bottom
  125. });
  126. }
  127. else
  128. {
  129. transformGroup.Children.Add(new TranslateTransform()
  130. {
  131. X = 0,
  132. Y = ((e.PrintableArea.Height -(element.ActualHeight * scale)) / 2) - PageMargin.Bottom
  133. });
  134. }
  135. }
  136.  
  137. if (HorizontalAlignment == HorizontalAlignment.Left)
  138. {
  139. //Now move to Left
  140. if (PrintLandscape)
  141. {
  142. transformGroup.Children.Add(new TranslateTransform()
  143. {
  144. X = PageMargin.Left - (e.PrintableArea.Width -(element.ActualHeight * scale)) / 2,
  145. Y = 0
  146. });
  147. }
  148. else
  149. {
  150. transformGroup.Children.Add(new TranslateTransform()
  151. {
  152. X = PageMargin.Left - (e.PrintableArea.Width -(element.ActualWidth * scale)) / 2,
  153. Y = 0
  154. });
  155. }
  156. }
  157. else if (HorizontalAlignment == HorizontalAlignment.Right)
  158. {
  159. //Now move to Right
  160. if (PrintLandscape)
  161. {
  162. transformGroup.Children.Add(new TranslateTransform()
  163. {
  164. X = ((e.PrintableArea.Width -(element.ActualHeight * scale)) / 2) - PageMargin.Right,
  165. Y = 0
  166. });
  167. }
  168. else
  169. {
  170. transformGroup.Children.Add(new TranslateTransform()
  171. {
  172. X = ((e.PrintableArea.Width -(element.ActualWidth * scale)) / 2) - PageMargin.Right,
  173. Y = 0
  174. });
  175. }
  176. }
  177.  
  178. e.PageVisual = element;
  179. e.PageVisual.RenderTransform = transformGroup;
  180.  
  181. //Increment to next item,
  182. currentItemIndex++;
  183.  
  184. //If the currentItemIndex is less than the number of elements, keep printing
  185. e.HasMorePages = currentItemIndex < elements.Count;
  186. };
  187.  
  188. printDocument.EndPrint += delegate(object sender, EndPrintEventArgs e)
  189. {
  190. foreach (var item in elements)
  191. {
  192. FrameworkElement element = item as FrameworkElement;
  193. //Reset everything...
  194. TransformGroup transformGroup = new TransformGroup();
  195. transformGroup.Children.Add(new ScaleTransform() { ScaleX = 1, ScaleY = 1 }); //缩放动画
  196. transformGroup.Children.Add(new RotateTransform() { Angle = 0 }); //旋转动画
  197. transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = 0 }); //偏移动画
  198. element.RenderTransform = transformGroup;
  199. }
  200.  
  201. //Callback to complete
  202. if (OnPrintComplete != null)
  203. {
  204. OnPrintComplete();
  205. }
  206. };
  207.  
  208. printDocument.Print(Document);
  209. }
  210. }

调用这个类:

  1. private void btnPrint_Click(object sender, RoutedEventArgs e)
  2. {
  3. Extensions.Print(GPrint, "MyPrint",
  4. HorizontalAlignment.Center, VerticalAlignment.Top,
  5. new Thickness(10, 0, 10, 0), true, true, null);
  6. }

这样就能完整的打印了,不过打印出来的效果可能是横向的。

C# 使用Silverlight打印图片的更多相关文章

  1. Silverlight打印注意事项

    1.Silverlight的打印功能从版本5开始才支持矢量打印,这不但要求打印机支持矢量打印,而且还要安装相应的打印驱动程序. 测试你的打印机是否支持矢量打印,可以参考:如何用C#代码检测打印机和驱动 ...

  2. 关于silverlight打印模糊的问题

         今天做silverlight打印实现时,发现一个问题,就是sl打印处理的文字很模糊          这样肯定不行撒,于是开始找解决办法,首先想到的是silverlight中文显示的问题,好 ...

  3. C# 热敏打印机 Socket 网络链接 打印 图片

    C# 热敏打印机 Socket 网络链接 打印 图片 (一) http://www.cnblogs.com/rinack/p/4838211.html C# 热敏打印机 Socket 网络链接 打印 ...

  4. silverlight 打印

    加引用: using System.Windows.Printing; xaml文件里: //定义图片和文本打印变量  PrintDocument printImage; public BeginCo ...

  5. LODOP用ADD_PRINT_IMAGE语句缩放打印图片

    LODOP提高输出图片质量的方法:1.用ADD_PRINT_IMAGE语句打印图片,而且img元素的width和height属性要去掉或者设置足够大,这样就可以让下载引擎传给Lodop图片质量足够好; ...

  6. Python+OpenCV图像处理(二)——打印图片属性、设置图片存储路径、电脑摄像头的调取和显示

    一. 打印图片属性.设置图片存储路径 代码如下: #打印图片的属性.保存图片位置 import cv2 as cv import numpy as np #numpy是一个开源的Python科学计算库 ...

  7. Silverlight 中图片路径的设置

    在Silverlight中图片的设置方法有几种 如上图在一个工程中有个images文件夹,buttons.xaml页面中的Image控件要引用一张图片 第一种方法 xaml: <Image x: ...

  8. C# 热敏打印机 小票打印机 打印图片

    最近一直在研究并口小票打印机打印图片问题,这也是第一次和硬件打交道,不过还好,最终成功了. 这是DEMO的窗体: 下面是打印所需要调用的代码: 因为我们这里主要是打印条形码和二维码,所以以条形码和二维 ...

  9. C#热敏打印图片 串口打印图片

    原文:C#热敏打印图片 串口打印图片 如图,一步一步慢慢调出来的 //串口通信类 public System.IO.Ports.SerialPort serialPort = null; serial ...

随机推荐

  1. 7——C++类的使用

     定义了一个类之后,便可以如同用int.double等类型符声明简单变量一样,创建该类的对象,称为类的实例化.           类的定义实际上是定义了一种类型,类不接收或存储具体的值,只作为生成具 ...

  2. this与super的区别

    调用super()的语句必须要写在子类构造方法的第一行. super()是在子类中调用父类的构造方法:this()是在同一类中调用其它方法. super()和this()都需要放在构造函数的第一行. ...

  3. kettle 通过JDBC 连接SQL Server(Error occurred while trying to connect to the database)

    在连接数据(MS SQLServer 2008)发现:Error occurred while trying to connect to the database 然后找资料看,都不是问题所在,最后一 ...

  4. Redis-缓存击穿/穿透/雪崩

    缓存击穿/穿透/雪崩 Intro 使用缓存需要了解几个缓存问题,缓存击穿.缓存穿透以及缓存雪崩,需要了解它们产生的原因以及怎么避免,尤其是当你打算设计自己的缓存框架的时候需要考虑如何处理这些问题. 缓 ...

  5. Delphi GridPanel Percent百分比设置

    可能很多人都有这个困扰,为什么每次设置一个百分比后,值都会改变,只有设置成absolute​才会正常,经摸索发现,是因为精度引起,设置percent的时候,需要将精确到多个小数位.如要有3列,需要设置 ...

  6. 数组与List互转的坑

    一.数组转List 非原始类型的数组转List有很多种方式:假设有Integer[] arr = {"a", "b", "c"}; 1.Li ...

  7. java扫描仪上传文件

    问题: 项目中有一个功能,原来是用ckfinder做的,可以选择本地图片上传至服务器,然后将服务器的图片显示在浏览器中,并可以将图片地址保存到数据库:现在客户觉得麻烦,提出连接扫描仪扫描后直接上传至服 ...

  8. Leetcode_131. Palindrome Partitioning_[DFS]

    题目链接 Given a string s, partition s such that every substring of the partition is a palindrome. Retur ...

  9. 【Java】Java URLDecoder异常Illegal hex characters in escape (%)

    如果收到的HTTP请求参数(URL中的GET请求)中有一个字符串,是中文,比如“10%是黄段子”,服务器段使用URLDecoder.decode就会出现此异常.URL只能使用英文字母.阿拉伯数字和某些 ...

  10. Delphi实现获取磁盘空间大小的方法

    unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ...