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

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

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值,标识是否多页。
一个简单的例子:

       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;
}

分页打印的例子:

 //当前打印的行的索引,用于遍历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;
}

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

 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);
}
}

调用这个类:

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);
}

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

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. linux基础知识(三)

    添加用户 •useradd -d 家目录 -g 组名 -G 组集合(逗号间隔) -p 密码 -s 用户shell程序 用户名 •useradd -d /usr/local/nginx/ -g ngin ...

  2. bzoj3589 动态树 树链剖分+容斥

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3589 题解 事件 \(0\) 不需要说,直接做就可以了. 事件 \(1\) 的话,考虑如果直接 ...

  3. django 修改字段后,同步数据库,失败:django.db.utils.InternalError: (1054, "Unknown column 'api_config.project_id_id' in 'field list'")

    问题原因是,修改字段后,同步失败了,然后执行查询的时候,就会提示这个错误,这个字段没有 最暴力的方法可以直接在数据库中修改字段,但是修改后,models没同步,可能会存在问题,因此开始我的百度之旅(这 ...

  4. Linux命令行工具之pidstat命令

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484624.html pidstat命令就可以帮助我们监测到具体线程的上下文切换 通过pidstat ...

  5. [洛谷P2661] NOIP2015 信息传递

    问题描述 有 n 个同学(编号为 1 到 n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 i 的同学的信息传递对象是编号为 Ti 的同学. 游戏开始时,每人都只知道 ...

  6. DELPHI FMX 获取系统版本 ANDROID IOS通用

    引用System.sysutils function getOSInfo:String; begin result:= fomrat('%s:%d.%d', TOSVersion.Name,TOSVe ...

  7. python编程中的一个经典错误之list引用

    请看下面代码 class User: def __init__(self, name, hobby=[]): self.name = name self.hobby = hobby def add_h ...

  8. Dubbo学习-5-监控中心simpleMonitor搭建

    之前已经下载好的dubbo-admin-master源码中,有dubbo-monitor-simple工程,同理,使用maven命令打包成一个可执行的jar包: 1.进入dubbo-monitor-s ...

  9. Python3解leetcode Reach a Number

    问题描述: You are standing at position 0 on an infinite number line. There is a goal at position target. ...

  10. php stristr()函数 语法

    php stristr()函数 语法 作用:返回一个字符串在另一个字符串中开始位置到结束的字符串,不区分大小写.直线电机厂家怎么样? 语法:stristr(string,search,before_s ...