Simplified and Consistent Printing in Silverlight - with Page Margins, Shrink to Fit, and Landscape printing


/ Published in: C#
Save to your folder(s)

The following extension method allows you to call Print() on any FrameworkElement, UIElement or group of elements, and print with a variety of settings such as landscape mode, shrink to fit, page centering, and more


Copy this code and paste it in your HTML
  1. public static class Extensions
  2. {
  3. public static void Print(this FrameworkElement element, string Document, HorizontalAlignment HorizontalAlignment, VerticalAlignment VerticalAlignment, Thickness PageMargin, bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete)
  4. {
  5. Print(new List<FrameworkElement>() { element }, Document, HorizontalAlignment, VerticalAlignment, PageMargin, PrintLandscape, ShrinkToFit, OnPrintComplete);
  6. }
  7.  
  8. public static void Print(this UIElementCollection elements, string Document, HorizontalAlignment HorizontalAlignment, VerticalAlignment VerticalAlignment, Thickness PageMargin, bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete)
  9. {
  10. Print(elements.ToList(), Document, HorizontalAlignment, VerticalAlignment, PageMargin, PrintLandscape, ShrinkToFit, OnPrintComplete);
  11. }
  12.  
  13. public static void Print<T>(this List<T> elements, string Document, HorizontalAlignment HorizontalAlignment, VerticalAlignment VerticalAlignment, Thickness PageMargin, bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete)
  14. {
  15. PrintDocument printDocument = new PrintDocument();
  16. PageMargin = PageMargin == null ? new Thickness(10) : PageMargin;
  17. Document = (string.IsNullOrEmpty(Document)) ? "Print Document" : Document;
  18. int currentItemIndex = 0;
  19. printDocument.PrintPage += delegate(object sender, PrintPageEventArgs evt)
  20. {
  21. if (!typeof(FrameworkElement).IsAssignableFrom(elements[currentItemIndex].GetType()))
  22. {
  23. throw new Exception("Element must be an object inheriting from FrameworkElement");
  24. }
  25.  
  26. FrameworkElement element = elements[currentItemIndex] as FrameworkElement;
  27.  
  28. if (element.Parent == null || element.ActualWidth == double.NaN || element.ActualHeight == double.NaN)
  29. {
  30. throw new Exception("Element must be rendered, and must have a parent in order to print.");
  31. }
  32.  
  33. TransformGroup transformGroup = new TransformGroup();
  34.  
  35. //First move to middle of page...
  36. transformGroup.Children.Add(new TranslateTransform() { X = (evt.PrintableArea.Width - element.ActualWidth) / 2, Y = (evt.PrintableArea.Height - element.ActualHeight) / 2 });
  37. double scale = 1;
  38. if (PrintLandscape)
  39. {
  40. //Then, rotate around the center
  41. transformGroup.Children.Add(new RotateTransform() { Angle = 90, CenterX = evt.PrintableArea.Width / 2, CenterY = evt.PrintableArea.Height / 2 });
  42.  
  43. if (ShrinkToFit)
  44. {
  45. if ((element.ActualWidth + PageMargin.Left + PageMargin.Right) > evt.PrintableArea.Height)
  46. {
  47. scale = Math.Round(evt.PrintableArea.Height / (element.ActualWidth + PageMargin.Left + PageMargin.Right), 2);
  48. }
  49. if ((element.ActualHeight + PageMargin.Top + PageMargin.Bottom) > evt.PrintableArea.Width)
  50. {
  51. double scale2 = Math.Round(evt.PrintableArea.Width / (element.ActualHeight + PageMargin.Top + PageMargin.Bottom), 2);
  52. scale = (scale2 < scale) ? scale2 : scale;
  53. }
  54. }
  55. }
  56. else if (ShrinkToFit)
  57. {
  58. //Scale down to fit the page + margin
  59.  
  60. if ((element.ActualWidth + PageMargin.Left + PageMargin.Right) > evt.PrintableArea.Width)
  61. {
  62. scale = Math.Round(evt.PrintableArea.Width / (element.ActualWidth + PageMargin.Left + PageMargin.Right), 2);
  63. }
  64. if ((element.ActualHeight + PageMargin.Top + PageMargin.Bottom) > evt.PrintableArea.Height)
  65. {
  66. double scale2 = Math.Round(evt.PrintableArea.Height / (element.ActualHeight + PageMargin.Top + PageMargin.Bottom), 2);
  67. scale = (scale2 < scale) ? scale2 : scale;
  68. }
  69. }
  70.  
  71. //Scale down to fit the page + margin
  72. if (scale != 1)
  73. {
  74. transformGroup.Children.Add(new ScaleTransform() { ScaleX = scale, ScaleY = scale, CenterX = evt.PrintableArea.Width / 2, CenterY = evt.PrintableArea.Height / 2 });
  75. }
  76.  
  77. if (VerticalAlignment == VerticalAlignment.Top)
  78. {
  79. //Now move to Top
  80. if (PrintLandscape)
  81. {
  82. transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = PageMargin.Top - (evt.PrintableArea.Height - (element.ActualWidth * scale)) / 2 });
  83. }
  84. else
  85. {
  86. transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = PageMargin.Top - (evt.PrintableArea.Height - (element.ActualHeight * scale)) / 2 });
  87. }
  88. }
  89. else if (VerticalAlignment == VerticalAlignment.Bottom)
  90. {
  91. //Now move to Bottom
  92. if (PrintLandscape)
  93. {
  94. transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = ((evt.PrintableArea.Height - (element.ActualWidth * scale)) / 2) - PageMargin.Bottom });
  95. }
  96. else
  97. {
  98. transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = ((evt.PrintableArea.Height - (element.ActualHeight * scale)) / 2) - PageMargin.Bottom });
  99. }
  100. }
  101.  
  102. if (HorizontalAlignment == HorizontalAlignment.Left)
  103. {
  104. //Now move to Left
  105. if (PrintLandscape)
  106. {
  107. transformGroup.Children.Add(new TranslateTransform() { X = PageMargin.Left - (evt.PrintableArea.Width - (element.ActualHeight * scale)) / 2, Y = 0 });
  108. }
  109. else
  110. {
  111. transformGroup.Children.Add(new TranslateTransform() { X = PageMargin.Left - (evt.PrintableArea.Width - (element.ActualWidth * scale)) / 2, Y = 0 });
  112. }
  113. }
  114. else if (HorizontalAlignment == HorizontalAlignment.Right)
  115. {
  116. //Now move to Right
  117. if (PrintLandscape)
  118. {
  119. transformGroup.Children.Add(new TranslateTransform() { X = ((evt.PrintableArea.Width - (element.ActualHeight * scale)) / 2) - PageMargin.Right, Y = 0 });
  120. }
  121. else
  122. {
  123. transformGroup.Children.Add(new TranslateTransform() { X = ((evt.PrintableArea.Width - (element.ActualWidth * scale)) / 2) - PageMargin.Right, Y = 0 });
  124. }
  125. }
  126.  
  127. evt.PageVisual = element;
  128. evt.PageVisual.RenderTransform = transformGroup;
  129.  
  130. //Increment to next item,
  131. currentItemIndex++;
  132.  
  133. //If the currentItemIndex is less than the number of elements, keep printing
  134. evt.HasMorePages = currentItemIndex < elements.Count;
  135. };
  136.  
  137. printDocument.EndPrint += delegate(object sender, EndPrintEventArgs evt)
  138. {
  139. foreach (var item in elements)
  140. {
  141. FrameworkElement element = item as FrameworkElement;
  142. //Reset everything...
  143. TransformGroup transformGroup = new TransformGroup();
  144. transformGroup.Children.Add(new ScaleTransform() { ScaleX = 1, ScaleY = 1 });
  145. transformGroup.Children.Add(new RotateTransform() { Angle = 0 });
  146. transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = 0 });
  147. element.RenderTransform = transformGroup;
  148. }
  149.  
  150. //Callback to complete
  151. if (OnPrintComplete != null)
  152. {
  153. OnPrintComplete();
  154. }
  155. };
  156.  
  157. printDocument.Print(Document);
  158. }
  159. }

URL: http://www.codeproject.com/KB/silverlight/SilverlightEasyPrint.aspx

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.