方法有下面幾種
1, 使用PrintDialog::PrintVisual
public bool PrintVisual(FrameworkElement source)
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
if (printDlg.ShowDialog() == true)
{
printDlg.PrintVisual(source, "PrintVisual");
return true;
}
return false;
}
2, 轉成Bitmap圖,再列印
double width = source.ActualWidth;
double height = source.ActualHeight;
RenderTargetBitmap renderTarget = new RenderTargetBitmap(
(int)width, (int)height, 96, 96, PixelFormats.Default);
renderTarget.Render(source);
// BitmapSourceをBitmapに転換
System.Drawing.Bitmap bitmap;
MemoryStream outStream = new MemoryStream();
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
pngEncoder.Save(outStream);
bitmap = new System.Drawing.Bitmap(outStream);
printBridge.print(bitmap);
補充說明,轉成位圖的格式,這裡用了png格式,原因是當控件的背景色是透明(transparent)時,jpg和map格式圖像背景色都變成了黑色。。
printBridge的print的實作如下:
int HpPrintBridge::print(Image^ data)
{
_data = data;
PrintDocument^ pd = gcnew PrintDocument;
pd->PrintPage += gcnew PrintPageEventHandler( this, &HpPrintBridge::pd_PrintPage );
pd->Print();
return 0;
}
void HpPrintBridge::pd_PrintPage( Object^ /*sender*/, PrintPageEventArgs^ ev )
{
ev->Graphics->DrawImage(_data, 0, 0);
}
void HpPrintBridge::pd_PrintPage( Object^ /*sender*/, PrintPageEventArgs^ ev )
{
ev->Graphics->DrawImage(_data, 0, 0);
}
3,将vistual控件先轉換為xps document ,再轉換FlowDocument,再列印。
參照: 點選打開連結
(sample示例代碼有異常,無法執行。)
列印中有時會超出頁面,一張紙打不下來。可用下面的辦法,先得到縮放比例,再列印。
private PrintCapabilities GetPrintCapabilities(bool isDefaultPrint)
{
System.Printing.PrintCapabilities capabilities = null;
if (isDefaultPrint)
{
var localPrintServer = new LocalPrintServer();
// Retrieving collection of local printer on user machine
var localPrinterCollection =
localPrintServer.GetPrintQueues();
var localPrinterEnumerator =
localPrinterCollection.GetEnumerator();
if (localPrinterEnumerator.MoveNext())
{
// Get PrintQueue from first available printer
PrintQueue printQueue = (PrintQueue)localPrinterEnumerator.Current;
capabilities = printQueue.GetPrintCapabilities();
}
}
else
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
if (printDlg.ShowDialog() == true)
{
capabilities = printDlg.PrintQueue.GetPrintCapabilities(printDlg.PrintTicket);
}
}
return capabilities;
}
public bool PrintVisualAutoFitPage(FrameworkElement source, bool isDefaultPrint)
{
PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
System.Printing.PrintCapabilities capabilities = GetPrintCapabilities(isDefaultPrint);
if(capabilities != null){
// 印刷 get scale of the print wrt to screen of WPF visual
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / source.ActualWidth,
capabilities.PageImageableArea.ExtentHeight / source.ActualHeight);
//元のTransformを一時に保留
Transform oldTransform = source.LayoutTransform;
var oldSize = new System.Windows.Size(source.ActualWidth, source.ActualHeight);
//Transform the Visual to scale
this.LayoutTransform = new ScaleTransform(scale, scale);
//get the size of the printer page
System.Windows.Size sz = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//now print the visual to printer to fit on the one page.
printDlg.PrintVisual(source, "PrintVisualAutoFitPage");
source.LayoutTransform = oldTransform;
source.Measure(oldSize);
return true;
}
return false;
}
根據scale,對方法二做如下修改
private void PrintByImage(FrameworkElement source, bool isDefaultPrint)
{
double scale = GetPrintScale(source, isDefaultPrint);
//double actualHeight = source.ActualWidth;
//double actualWidth = source.ActualHeight;
double actualHeight = source.RenderSize.Height;
double actualWidth = source.RenderSize.Width;
double renderHeight = actualHeight * scale;
double renderWidth = actualWidth * scale;
RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Default);
VisualBrush sourceBrush = new VisualBrush(source);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
using (drawingContext)
{
drawingContext.PushTransform(new ScaleTransform(scale, scale));
drawingContext.DrawRectangle(sourceBrush, null, new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);
// BitmapSourceをBitmapに転換
System.Drawing.Bitmap bitmap;
MemoryStream outStream = new MemoryStream();
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
pngEncoder.Save(outStream);
bitmap = new System.Drawing.Bitmap(outStream);
obj.print(bitmap);
}