摘自:http://www.cnblogs.com/jiajiayuan/archive/2012/04/13/2444246.htmlhtml
Silverlight中的打印只有一個類,那就是PrintDocment這個對象來實現。
下面我用兩種方法來實現Silverlight的打印:
第一種:less
private void btnPrint_Click(object sender, RoutedEventArgs e) { PrintDocument document = new PrintDocument(); // tell the API what to print document.PrintPage += (s, args) => { args.PageVisual = GPrint; }; // call the Print() with a proper name which will be visible in the Print Queue document.Print("Silverlight Print Application Demo"); }
第二種:
實現方式也很簡單,其實只需兩個步驟便可完成,即綁定PrintDocument的PrintPage事件和調用Print方法。動畫
PrintDocument document = new PrintDocument(); document.PrintPage += documentImage_PrintPage; document.Print("Image Document");
這個就完成了一個打印,其中PrintPage事件是最爲重要的,由於整個打印的工做都是在這個事件中完成的,另外該事件的參數 PrintPageEventArgs構成了整個打印過程當中的屬性的設置;Print方法須要傳遞一個參數,參數爲打印的文件的名稱,在調用該方法的時候 開始觸發一系列的打印事件。
PrintPageEventArgs類型的屬性:
PrintableArea:獲取一個Size類型的值,表示打印的範圍,分別表示Height和Width,若是打印的部分超出了區域,則被截取。
PageMargins:獲取打印頁的Margin值。
PageVisual:設置要打印的對象,能夠是一個TextBlock、Image,也能夠是一個複雜的元素(Grid或者Canvas)。
HasMorePages:一個bool值,標識是否多頁。
一個簡單的例子:this
private void btnPrintImage_Click(object sender, RoutedEventArgs e) { PrintDocument document = new PrintDocument(); document.PrintPage += new EventHandler<PrintPageEventArgs>(document_PrintPage); document.Print("Print Image"); } void document_PrintPage(object sender, PrintPageEventArgs e) { Image imagePrint = new Image(); imagePrint.Source = img.Source; imagePrint.Height = e.PrintableArea.Height; imagePrint.Width = e.PrintableArea.Width; e.PageVisual = imagePrint; e.HasMorePages = false; }
分頁打印的例子:spa
//當前打印的行的索引,用於遍歷ListBox.Items private int listPrintIndex; private void btnPrintList_Click(object sender, RoutedEventArgs e) { //初始值爲0 listPrintIndex = 0; PrintDocument document = new PrintDocument(); document.PrintPage += new EventHandler<PrintPageEventArgs>(document_PrintPage); document.Print("Print List"); } //設置每一項之間的間距 private int extraMargin = 50; void document_PrintPage(object sender, PrintPageEventArgs e) { //定義一個打印的元素 Canvas printSurface = new Canvas(); e.PageVisual = printSurface; //獲得最頂端位置 double topPosition = e.PageMargins.Top + extraMargin; //遍歷當前的ListBox.Items while (listPrintIndex<lstPrint.Items.Count) { //實例化TextBlock用來存放ListItem的值 TextBlock txt = new TextBlock(); txt.FontSize = 30; //獲得ListBox每一項的值 txt.Text = lstPrint.Items[listPrintIndex].ToString(); double measuredHeight = txt.ActualHeight; //若是打印的當前行高度不合適的話,則進行分頁 if (measuredHeight>(e.PrintableArea.Height- topPosition- extraMargin)) { e.HasMorePages = true; return ; } //設置TextBlock在Canvas中的位置 txt.SetValue(Canvas.TopProperty, topPosition); txt.SetValue(Canvas.LeftProperty, e.PageMargins.Left + extraMargin); //將TextBlock添加到打印的元素中去 printSurface.Children.Add(txt); listPrintIndex++; //追加高度 topPosition = topPosition + measuredHeight; } e.HasMorePages = false; }
有時咱們會發現打印的圖片並不完整,這樣就須要一個類:code
public static class Extensions { public static void Print(this FrameworkElement element, string Document, HorizontalAlignment HorizontalAlignment, VerticalAlignment VerticalAlignment, Thickness PageMargin, bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete) { Print(new List<FrameworkElement>() { element }, Document, HorizontalAlignment, VerticalAlignment, PageMargin, PrintLandscape, ShrinkToFit, OnPrintComplete); } public static void Print<T>(this List<T> elements, string Document, HorizontalAlignment HorizontalAlignment, VerticalAlignment VerticalAlignment, Thickness PageMargin, bool PrintLandscape, bool ShrinkToFit, Action OnPrintComplete) { PrintDocument printDocument = new PrintDocument(); PageMargin = PageMargin == null ? new Thickness(10) : PageMargin; Document = (string.IsNullOrEmpty(Document)) ? "Print Document" : Document; int currentItemIndex = 0; printDocument.PrintPage += (s, e) => { if (!typeof(FrameworkElement).IsAssignableFrom(elements[currentItemIndex].GetType())) { throw new Exception("Element must be an " +"object inheriting from FrameworkElement"); } FrameworkElement element = elements[currentItemIndex] as FrameworkElement; if (element.Parent == null || element.ActualWidth == double.NaN ||element.ActualHeight == double.NaN) { throw new Exception("Element must be rendered, " + "and must have a parent in order to print."); } TransformGroup transformGroup = new TransformGroup(); //First move to middle of page... 首先移動到頁面的中間 transformGroup.Children.Add(new TranslateTransform() //TranslateTransform偏移動畫 { X = (e.PrintableArea.Width - element.ActualWidth) / 2, Y = (e.PrintableArea.Height - element.ActualHeight) / 8 }); double scale = 1; if (PrintLandscape) //若是打印空白 須要旋轉 { //Then, rotate around the center 而後旋轉到中心 transformGroup.Children.Add(new RotateTransform() { Angle = 90, CenterX = e.PrintableArea.Width / 2, CenterY = e.PrintableArea.Height / 2 }); if (ShrinkToFit) //若是自適應大小 { if ((element.ActualWidth + PageMargin.Left +PageMargin.Right) > e.PrintableArea.Height) //若是寬度大於紙張的高度 { //Math.Round 方法 將值舍入到最接近的整數或指定的小數位數。 scale = Math.Round(e.PrintableArea.Height /(element.ActualWidth + PageMargin.Left + PageMargin.Right), 2); } if ((element.ActualHeight + PageMargin.Top + PageMargin.Bottom) > e.PrintableArea.Width) //若是高度大於紙張的寬度 { double scale2 = Math.Round(e.PrintableArea.Width /(element.ActualHeight + PageMargin.Top + PageMargin.Bottom), 2); scale = (scale2 < scale) ? scale2 : scale; } } } else if (ShrinkToFit) //若是不打印空白並自適應大小 不須要旋轉 { //Scale down to fit the page + margin if ((element.ActualWidth + PageMargin.Left + PageMargin.Right) > e.PrintableArea.Width) //若是寬度大於紙張的寬度 { scale = Math.Round(e.PrintableArea.Width /(element.ActualWidth + PageMargin.Left + PageMargin.Right), 2); } if ((element.ActualHeight + PageMargin.Top + PageMargin.Bottom) > e.PrintableArea.Height) //若是高度大於紙張的高度 { double scale2 = Math.Round(e.PrintableArea.Height /(element.ActualHeight + PageMargin.Top + PageMargin.Bottom), 2); scale = (scale2 < scale) ? scale2 : scale; } } //Scale down to fit the page + margin if (scale != 1) { transformGroup.Children.Add(new ScaleTransform() //ScaleTransform縮放動畫 { ScaleX = scale, ScaleY = scale, CenterX = e.PrintableArea.Width / 2, CenterY = e.PrintableArea.Height / 2 }); } if (VerticalAlignment == VerticalAlignment.Top) { //Now move to Top if (PrintLandscape) { transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = PageMargin.Top - (e.PrintableArea.Height -(element.ActualWidth * scale)) / 2 }); } else { transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = PageMargin.Top - (e.PrintableArea.Height -(element.ActualHeight * scale)) / 2 }); } } else if (VerticalAlignment == VerticalAlignment.Bottom) { //Now move to Bottom if (PrintLandscape) { transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = ((e.PrintableArea.Height -(element.ActualWidth * scale)) / 2) - PageMargin.Bottom }); } else { transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = ((e.PrintableArea.Height -(element.ActualHeight * scale)) / 2) - PageMargin.Bottom }); } } if (HorizontalAlignment == HorizontalAlignment.Left) { //Now move to Left if (PrintLandscape) { transformGroup.Children.Add(new TranslateTransform() { X = PageMargin.Left - (e.PrintableArea.Width -(element.ActualHeight * scale)) / 2, Y = 0 }); } else { transformGroup.Children.Add(new TranslateTransform() { X = PageMargin.Left - (e.PrintableArea.Width -(element.ActualWidth * scale)) / 2, Y = 0 }); } } else if (HorizontalAlignment == HorizontalAlignment.Right) { //Now move to Right if (PrintLandscape) { transformGroup.Children.Add(new TranslateTransform() { X = ((e.PrintableArea.Width -(element.ActualHeight * scale)) / 2) - PageMargin.Right, Y = 0 }); } else { transformGroup.Children.Add(new TranslateTransform() { X = ((e.PrintableArea.Width -(element.ActualWidth * scale)) / 2) - PageMargin.Right, Y = 0 }); } } e.PageVisual = element; e.PageVisual.RenderTransform = transformGroup; //Increment to next item, currentItemIndex++; //If the currentItemIndex is less than the number of elements, keep printing e.HasMorePages = currentItemIndex < elements.Count; }; printDocument.EndPrint += delegate(object sender, EndPrintEventArgs e) { foreach (var item in elements) { FrameworkElement element = item as FrameworkElement; //Reset everything... TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(new ScaleTransform() { ScaleX = 1, ScaleY = 1 }); //縮放動畫 transformGroup.Children.Add(new RotateTransform() { Angle = 0 }); //旋轉動畫 transformGroup.Children.Add(new TranslateTransform() { X = 0, Y = 0 }); //偏移動畫 element.RenderTransform = transformGroup; } //Callback to complete if (OnPrintComplete != null) { OnPrintComplete(); } }; printDocument.Print(Document); } }
調用這個類:orm
private void btnPrint_Click(object sender, RoutedEventArgs e) { Extensions.Print(GPrint, "MyPrint", HorizontalAlignment.Center, VerticalAlignment.Top, new Thickness(10, 0, 10, 0), true, true, null); }
這樣就能完整的打印了,不過打印出來的效果多是橫向的。htm