1 sing System.Linq; 2 using System.Printing; 3 using System.Windows; 4 using System.Windows.Controls; 5 using System.Windows.Documents; 6 using System.Windows.Markup; 7 using System.Windows.Media; 8 using Telerik.Windows.Controls; 9 using Telerik.Windows.Controls.GridView; 10 11 namespace YourNamespaceHere 12 { 13 /// <summary> 14 /// Support Printing Related Methods 15 /// </summary> 16 public static class PrintExtensions 17 { 18 #region ___________ Properties ____________________________________________________________________________________________ 19 /// <summary> 20 /// Zoom Enumeration to specify how pages are stretched in print and preview 21 /// </summary> 22 public enum ZoomType 23 { 24 /// <summary> 25 /// 100% of normal size 26 /// </summary> 27 Full, 28 29 /// <summary> 30 /// Page Width (fit so one page stretches to full width) 31 /// </summary> 32 Width, 33 34 /// <summary> 35 /// Page Height (fit so one page stretches to full height) 36 /// </summary> 37 Height, 38 39 /// <summary> 40 /// Display two columsn of pages 41 /// </summary> 42 TwoWide 43 }; 44 #endregion 45 #region ___________ Methods _______________________________________________________________________________________________ 46 /// <summary> 47 /// Print element to a document 48 /// </summary> 49 /// <param name="element">GUI Element to Print</param> 50 /// <param name="dialog">Reference to Print Dialog</param> 51 /// <param name="orientation">Page Orientation (i.e. Portrait vs. Landscape)</param> 52 /// <returns>Destination document</returns> 53 static FixedDocument ToFixedDocument(FrameworkElement element, PrintDialog dialog, PageOrientation orientation = PageOrientation.Portrait) 54 { 55 dialog.PrintTicket.PageOrientation = orientation; 56 PrintCapabilities capabilities = dialog.PrintQueue.GetPrintCapabilities(dialog.PrintTicket); 57 Size pageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight); 58 Size extentSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight); 59 60 FixedDocument fixedDocument = new FixedDocument(); 61 62 element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 63 element.Arrange(new Rect(new Point(0, 0), element.DesiredSize)); 64 65 for (double y = 0; y < element.DesiredSize.Height; y += extentSize.Height) 66 { 67 for (double x = 0; x < element.DesiredSize.Width; x += extentSize.Width) 68 { 69 VisualBrush brush = new VisualBrush(element); 70 brush.Stretch = Stretch.None; 71 brush.AlignmentX = AlignmentX.Left; 72 brush.AlignmentY = AlignmentY.Top; 73 brush.ViewboxUnits = BrushMappingMode.Absolute; 74 brush.TileMode = TileMode.None; 75 brush.Viewbox = new Rect(x, y, extentSize.Width, extentSize.Height); 76 77 PageContent pageContent = new PageContent(); 78 FixedPage page = new FixedPage(); 79 ((IAddChild)pageContent).AddChild(page); 80 81 fixedDocument.Pages.Add(pageContent); 82 page.Width = pageSize.Width; 83 page.Height = pageSize.Height; 84 85 Canvas canvas = new Canvas(); 86 FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth); 87 FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight); 88 canvas.Width = extentSize.Width; 89 canvas.Height = extentSize.Height; 90 canvas.Background = brush; 91 92 page.Children.Add(canvas); 93 } 94 } 95 return fixedDocument; 96 } 97 98 /// <summary> 99 /// Convert GridView to Printer-Friendly version of a GridView 100 /// </summary> 101 /// <param name="source">Input GridView</param> 102 /// <returns>Printer-Friendly version of source</returns> 103 static GridViewDataControl ToPrintFriendlyGrid(GridViewDataControl source) 104 { 105 RadGridView grid = new RadGridView(); 106 107 grid.ItemsSource = source.ItemsSource; 108 grid.RowIndicatorVisibility = Visibility.Collapsed; 109 grid.ShowGroupPanel = false; 110 grid.CanUserFreezeColumns = false; 111 grid.IsFilteringAllowed = false; 112 grid.AutoExpandGroups = true; 113 grid.AutoGenerateColumns = false; 114 115 foreach (GridViewDataColumn column in source.Columns.OfType<GridViewDataColumn>()) 116 { 117 GridViewDataColumn newColumn = new GridViewDataColumn(); 118 newColumn.Width = column.ActualWidth; 119 newColumn.DisplayIndex = column.DisplayIndex; 120 //newColumn.DataMemberBinding = new System.Windows.Data.Binding(column.UniqueName); 121 newColumn.DataMemberBinding = column.DataMemberBinding; // Better to just copy the references to get all the custom formatting 122 newColumn.DataFormatString = column.DataFormatString; 123 newColumn.TextAlignment = column.TextAlignment; 124 newColumn.Header = column.Header; 125 newColumn.Footer = column.Footer; 126 grid.Columns.Add(newColumn); 127 } 128 129 StyleManager.SetTheme(grid, StyleManager.GetTheme(grid)); 130 131 grid.SortDescriptors.AddRange(source.SortDescriptors); 132 grid.GroupDescriptors.AddRange(source.GroupDescriptors); 133 grid.FilterDescriptors.AddRange(source.FilterDescriptors); 134 135 return grid; 136 } 137 138 /// <summary> 139 /// Perform a Print Preview on GridView source 140 /// </summary> 141 /// <param name="source">Input GridView</param> 142 /// <param name="orientation">Page Orientation (i.e. Portrait vs. Landscape)</param> 143 /// <param name="zoom">Zoom Enumeration to specify how pages are stretched in print and preview</param> 144 public static void PrintPreview(GridViewDataControl source, PageOrientation orientation = PageOrientation.Landscape, ZoomType zoom = ZoomType.TwoWide) 145 { 146 Window window = new Window(); 147 window.Title = "Print Preview"; 148 if (!string.IsNullOrWhiteSpace(source.ToolTip as string)) window.Title += " of " + source.ToolTip; 149 window.Width = SystemParameters.PrimaryScreenWidth * 0.92; 150 window.Height = SystemParameters.WorkArea.Height; 151 window.Left = constrain(SystemParameters.VirtualScreenWidth - SystemParameters.PrimaryScreenWidth, 0, SystemParameters.VirtualScreenWidth - 11); 152 window.Top = constrain(0, 0, SystemParameters.VirtualScreenHeight - 25); 153 154 DocumentViewer viewer = new DocumentViewer(); 155 viewer.Document = ToFixedDocument(ToPrintFriendlyGrid(source), new PrintDialog(), orientation); 156 Zoom(viewer, zoom); 157 window.Content = viewer; 158 159 window.ShowDialog(); 160 } 161 162 /// <summary> 163 /// Constrain val to the range [val_min, val_max] 164 /// </summary> 165 /// <param name="val">Value to be constrained</param> 166 /// <param name="val_min">Minimum that will be returned if val is less than val_min</param> 167 /// <param name="val_max">Maximum that will be returned if val is greater than val_max</param> 168 /// <returns>val in [val_min, val_max]</returns> 169 private static double constrain(double val, double val_min, double val_max) 170 { 171 if (val < val_min) return val_min; 172 else if (val > val_max) return val_max; 173 else return val; 174 } 175 176 /// <summary> 177 /// Perform a Print on GridView source 178 /// </summary> 179 /// <param name="source">Input GridView</param> 180 /// <param name="showDialog">True to show print dialog before printing</param> 181 /// <param name="orientation">Page Orientation (i.e. Portrait vs. Landscape)</param> 182 /// <param name="zoom">Zoom Enumeration to specify how pages are stretched in print and preview</param> 183 public static void Print(GridViewDataControl source, bool showDialog = true, PageOrientation orientation = PageOrientation.Landscape, ZoomType zoom = ZoomType.TwoWide) 184 { 185 PrintDialog dialog = new PrintDialog(); 186 bool? dialogResult = showDialog ? dialog.ShowDialog() : true; 187 188 if (dialogResult == true) 189 { 190 DocumentViewer viewer = new DocumentViewer(); 191 viewer.Document = ToFixedDocument(ToPrintFriendlyGrid(source), dialog, orientation); 192 Zoom(viewer, zoom); 193 dialog.PrintDocument(viewer.Document.DocumentPaginator, ""); 194 } 195 } 196 197 /// <summary> 198 /// Scale viewer to size specified by zoom 199 /// </summary> 200 /// <param name="viewer">Document to zoom</param> 201 /// <param name="zoom">Zoom Enumeration to specify how pages are stretched in print and preview</param> 202 public static void Zoom(DocumentViewer viewer, ZoomType zoom) 203 { 204 switch (zoom) 205 { 206 case ZoomType.Height: viewer.FitToHeight(); break; 207 case ZoomType.Width: viewer.FitToWidth(); break; 208 case ZoomType.TwoWide: viewer.FitToMaxPagesAcross(2); break; 209 case ZoomType.Full: break; 210 } 211 } 212 #endregion 213 }