WPF 打印界面(控件)到A4纸
这次遇到一个需求,就是将整个界面打印在A4纸上。
需求清楚后,Bing一下关于打印,就找到一个类PrintDialog ,其中两个方法可能会用到:
特别是public void PrintVisual(Visual visual, string description)可以直接传一个控件就能打印出来了。试了一下后发现,只打印了部分,还有部分没打印出来。
继续Bing,就是看了一篇关于打印UserControl的文章 ,直接c+v到工程中,很强大,能打印且还分页打印了。但是界面布局变丑了,仔细研究了一下源码,是由于修改了界面的比率和宽度导致的。但是无论我怎么修改,一直没有达到理想的效果。我就想有没有其他的方法,不修改比率和宽度。答案是肯定有的,将整个界面按照一定的比率保存为图片(关于DPI,分辨率的知识,自行百度,因为我说不清楚),然后再打印出来,就可以了。
代码逻辑如下
1.初始化一个打印对象
public class ControlPrint
{
//A4纸的尺寸300dpi 的图像的像素是2480×3508
private const int A4_WIDTH_PIXEL = ;
private const int A4_HEIGTH_PIXEL = ; // 图片 和 界面 dpi比率
// 通常图片都是300 dpi 而是界面96 dpi(dpi dot per inch)
private readonly double IMAGE_DPI_SCALE = 300.0 / 96.0; //标准打印使用 300dpi
private readonly double PRINT_DPI_X = ;
private readonly double PRINT_DPI_Y = ; private PrintDialog _printer = null; public ControlPrint()
{
InitPrinter();
} private void InitPrinter()
{
_printer = new PrintDialog();
//灰度打印
_printer.PrintTicket.OutputColor = OutputColor.Grayscale;
}
..... }
2.打印:截图,将图片放到文档中,打印文档
........
/// <summary>
/// </summary>
/// <param name="control"></param>
/// <returns></returns>
public bool Print(FrameworkElement control)
{
if (null == control || null == _printer)
{
return false;
} try
{
//截图
var bitmapSrc = CaptureControlScreen(control);
//图片放在文档里
var fixedDoc = GenerateDocument(bitmapSrc);
//打印
_printer.PrintDocument(fixedDoc.DocumentPaginator, "print reprot");
return true;
}
catch (Exception)
{
return false;
}
}
.......
3.截图和创建文档。
......
/// <summary>
/// control to BitmapSource
/// https://blogs.msdn.microsoft.com/jaimer/2009/07/03/rendertargetbitmap-tips/
/// </summary>
/// <param name="control"></param>
/// <returns></returns>
private BitmapSource CaptureControlScreen(Visual control)
{
var bounds = VisualTreeHelper.GetDescendantBounds(control); var rtb = new RenderTargetBitmap((int)(bounds.Width * IMAGE_DPI_SCALE),
(int)(bounds.Height * IMAGE_DPI_SCALE),
PRINT_DPI_X, PRINT_DPI_Y,
PixelFormats.Pbgra32); var dv = new DrawingVisual();
using (DrawingContext ctx = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(control);
ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
return rtb;
} /// <summary>
/// document
/// </summary>
/// <param name="bmpSource"></param>
/// <returns></returns>
private FixedDocument GenerateDocument(BitmapSource bmpSource)
{
if (null == bmpSource)
{
return null;
}
var capabilities = _printer.PrintQueue.GetPrintCapabilities(_printer.PrintTicket); //append bitmap to control of image
var image = new Image();
image.Source = bmpSource;
image.VerticalAlignment = VerticalAlignment.Top;
image.HorizontalAlignment = HorizontalAlignment.Center;
image.Width = capabilities.PageImageableArea.ExtentWidth;
image.Height = capabilities.PageImageableArea.ExtentHeight; //append image to fixedpage
var printDocumentPage = new FixedPage();
printDocumentPage.Width = capabilities.PageImageableArea.ExtentWidth;
printDocumentPage.Height = capabilities.PageImageableArea.ExtentHeight;
printDocumentPage.HorizontalAlignment = HorizontalAlignment.Center;
printDocumentPage.Children.Add(image); //append fixedpage to pagecontent
var pageContent = new PageContent();
pageContent.HorizontalAlignment = HorizontalAlignment.Center;
((System.Windows.Markup.IAddChild)pageContent).AddChild(printDocumentPage); //append pagecontent to document
var fixedDoc = new FixedDocument();
fixedDoc.Pages.Add(pageContent);
return fixedDoc;
}
至此就完成了打印界面。需要注意的是,如果界面有滚动条的话,那打印的是滚动条里面的一层grid或者panel,这样才能完整的打印出。
WPF 打印界面(控件)到A4纸的更多相关文章
- wpf 深度复制控件,打印控件
原文:wpf 深度复制控件,打印控件 <Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.micr ...
- 解析大型.NET ERP系统 灵活复杂的界面控件Infragistics WinForms
Infragistics 是.NET平台优秀的控件供应商,囊括了WinForms,ASP.NET,Silverlight,WPF,Windows Phone等所有关于微软.NET技术的界面控件.借助于 ...
- WPF中Ribbon控件的使用
这篇博客将分享如何在WPF程序中使用Ribbon控件.Ribbon可以很大的提高软件的便捷性. 上面截图使Outlook 2010的界面,在Home标签页中,将所属的Menu都平铺的布局,非常容易的可 ...
- InteropBitmap指定内存,绑定WPF的Imag控件时刷新问题。
1.InteropBitmap指定内存,绑定WPF的Imag控件的Source属性 创建InteropBitmap的时候,像素的格式必须为PixelFormats.Bgr32, 如果不是的话在绑定到I ...
- 浅尝辄止WPF自定义用户控件(实现颜色调制器)
主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...
- Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决
有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...
- 深入理解MVC C#+HtmlAgilityPack+Dapper走一波爬虫 StackExchange.Redis 二次封装 C# WPF 用MediaElement控件实现视频循环播放 net 异步与同步
深入理解MVC MVC无人不知,可很多程序员对MVC的概念的理解似乎有误,换言之他们一直在错用MVC,尽管即使如此软件也能被写出来,然而软件内部代码的组织方式却是不科学的,这会影响到软件的可维护性 ...
- WPF 在image控件用鼠标拖拽出矩形
原文:WPF 在image控件用鼠标拖拽出矩形 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee ...
- WPF 曲线图表控件(自制)(二)
原文:WPF 曲线图表控件(自制)(二) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/775218 ...
随机推荐
- 我们最常见的UX设计交付成果有哪些?
以下内容由摹客团队翻译整理,仅供学习交流,摹客iDoc是支持智能标注和切图的产品协作设计神器. 有人会好奇,用户体验(UX)设计师每天都在做些什么呢?说实话,有很多事情!作为UX专家,需要将自己的设计 ...
- centos php 运行环境搭建
一.安装apache httpd rpm -qa|grep httpd //检查是否安装apache rpm -e 包名 --nodeps //若有则删除 PS:我没有删除,直接用的服务器原来的. y ...
- android 4.0 webview 无法播放视频
Android4.0+webview中不能播放网页视频解决方法: 1.修改AndroidManifest.xml文件 在application中添加如下属性 android:hardwareAccel ...
- Python 使用for...in...和 while 循环 实现8种格式的 九九乘法表
#九九乘法表 for...in .. #左下角 for i in range(1,10): for j in range(1,i+1): print(' %d×%d=%2d'%(j,i,i*j), e ...
- Select isnull(,)
类似于 select isnull(...,1) from table 这样的 isnull函数防止查询结果为空,防止接下来需要这个值时可能造成空指针异常
- BP神经网络测试MNIST记录
约定: 所有的初始化权值范围,如下,就是说更换激活函数的情况,没有过大的调整初始权重. if(randomMode==1): numpy.random.seed(seedWih) self.wih = ...
- java运行报错:nested exception is java.lang.NoSuchFieldError: INSTANCE,但使用@Test测试是好的
解决方法: 原因是,在tomcat里,同名不同版本的jar包,默认加载版本低的.我项目里有两个httpclient jar包.一个4.2.5 另一个是4.5.所以加载了4.2.5的,而我要用的是4. ...
- 2018.12.22 bzoj3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)
传送门 题意简述:给出一棵trietrietrie树,每个点表示一个字符,求树上所有路径组成的不同字串数.(叶子数≤20\le 20≤20) 由于有一个神奇的条件,考虑以每一个叶子为树根统计每个点到树 ...
- Lagrange 乘子法求最优解
clc clear syms x y z r1 r2 w f=x^+y^+z^+w^; g1=*x-y+z-w-; g2=x+y-z+w-; h=f-r1*g1 -r2*g2; hx=diff(h,x ...
- ZOJ 3156 Taxi (二分 + 二分匹配)
题意:给定 n 个人坐标, m 辆车的坐标,还有人的速度,要求每个人要进一辆不同的车,问你所有都进车的最短时间是多少. 析:首先二分时间 mid,很明显就是最后那个人进车的时间,然后如果把第 i 个人 ...