wpf打印控件 实现分页打印控件功能
因为 要实现打印 wpf listbox控件 数据特别多 要打印在 几张纸上 找了几天 都没有找到相关的例子
现在 解决了 在这里和大家分享一下
public void print(FrameworkElement ViewContainer)
{
FrameworkElement objectToPrint = ViewContainer as FrameworkElement;
PrintDialog printDialog = new PrintDialog();
printDialog.PrintTicket.PageOrientation = PageOrientation.Landscape;
if ((bool)printDialog.ShowDialog().GetValueOrDefault())
{
Mouse.OverrideCursor = Cursors.Wait;
PrintCapabilities capabilities =
printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
double dpiScale = 300.0 / 96.0;
FixedDocument document = new FixedDocument();
try {
objectToPrint.Width = capabilities.PageImageableArea.ExtentWidth;
objectToPrint.UpdateLayout();
objectToPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Size size = new Size(capabilities.PageImageableArea.ExtentWidth,
objectToPrint.DesiredSize.Height);
objectToPrint.Measure(size);
size = new Size(capabilities.PageImageableArea.ExtentWidth,
objectToPrint.DesiredSize.Height);
objectToPrint.Measure(size);
objectToPrint.Arrange(new Rect(size));
// Convert the UI control into a bitmap at 300 dpi
double dpiX = 300;
double dpiY = 300;
RenderTargetBitmap bmp = new RenderTargetBitmap(Convert.ToInt32(
capabilities.PageImageableArea.ExtentWidth * dpiScale),
Convert.ToInt32(objectToPrint.ActualHeight * dpiScale),
dpiX, dpiY, PixelFormats.Pbgra32);
bmp.Render(objectToPrint);
// Convert the RenderTargetBitmap into a bitmap we can more readily use
PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(bmp));
System.Drawing.Bitmap bmp2;
using (MemoryStream memoryStream = new MemoryStream())
{
png.Save(memoryStream);
bmp2 = new System.Drawing.Bitmap(memoryStream);
}
document.DocumentPaginator.PageSize =
new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
// break the bitmap down into pages
int pageBreak = 0;
int previousPageBreak = 0;
int pageHeight =
Convert.ToInt32(capabilities.PageImageableArea.ExtentHeight * dpiScale);
while (pageBreak < bmp2.Height - pageHeight)
{
pageBreak += pageHeight; // Where we thing the end of the page should be
// Keep moving up a row until we find a good place to break the page
while (!IsRowGoodBreakingPoint(bmp2, pageBreak)) pageBreak--;
PageContent pageContent = generatePageContent(bmp2, previousPageBreak,
pageBreak, document.DocumentPaginator.PageSize.Width,
document.DocumentPaginator.PageSize.Height, capabilities); document.Pages.Add(pageContent); previousPageBreak = pageBreak; }
// Last Page
PageContent lastPageContent = generatePageContent(bmp2, previousPageBreak,
bmp2.Height, document.DocumentPaginator.PageSize.Width,
document.DocumentPaginator.PageSize.Height, capabilities);
document.Pages.Add(lastPageContent);
}
finally
{
// Scale UI control back to the original so we don't effect what is on the screen
objectToPrint.Width = double.NaN;
objectToPrint.UpdateLayout();
objectToPrint.LayoutTransform = new ScaleTransform(1, 1);
Size size = new Size(capabilities.PageImageableArea.ExtentWidth,
capabilities.PageImageableArea.ExtentHeight);
objectToPrint.Measure(size);
objectToPrint.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth,
capabilities.PageImageableArea.OriginHeight), size));
Mouse.OverrideCursor = null;
}
printDialog.PrintDocument(document.DocumentPaginator, "Print Document Name");
} }
private PageContent generatePageContent(System.Drawing.Bitmap bmp, int top, int bottom, double pageWidth, double PageHeight, System.Printing.PrintCapabilities capabilities) {
FixedPage printDocumentPage = new FixedPage();
printDocumentPage.Width = pageWidth;
printDocumentPage.Height = PageHeight;
int newImageHeight = bottom - top;
System.Drawing.Bitmap bmpPage = bmp.Clone(new System.Drawing.Rectangle(0, top, bmp.Width, newImageHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Create a new bitmap for the contents of this page
Image pageImage = new Image();
BitmapSource bmpSource =
System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bmpPage.GetHbitmap(),
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(bmp.Width, newImageHeight));
pageImage.Source = bmpSource;
pageImage.VerticalAlignment = VerticalAlignment.Top;
// Place the bitmap on the page
printDocumentPage.Children.Add(pageImage);
PageContent pageContent = new PageContent();
((System.Windows.Markup.IAddChild)pageContent).AddChild(printDocumentPage);
FixedPage.SetLeft(pageImage, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(pageImage, capabilities.PageImageableArea.OriginHeight);
pageImage.Width = capabilities.PageImageableArea.ExtentWidth;
pageImage.Height = capabilities.PageImageableArea.ExtentHeight;
return pageContent; }
private bool IsRowGoodBreakingPoint(System.Drawing.Bitmap bmp, int row) {
double maxDeviationForEmptyLine = 1627500;
bool goodBreakingPoint = false;
if (rowPixelDeviation(bmp, row) < maxDeviationForEmptyLine)
goodBreakingPoint = true;
return goodBreakingPoint;
} private double rowPixelDeviation(System.Drawing.Bitmap bmp, int row)
{
int count = 0;
double total = 0;
double totalVariance = 0;
double standardDeviation = 0;
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0,
bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
int stride = bmpData.Stride;
IntPtr firstPixelInImage = bmpData.Scan0;
unsafe
{
byte* p = (byte*)(void*)firstPixelInImage;
p += stride * row; // find starting pixel of the specified row
for (int column = 0; column < bmp.Width; column++)
{
count++; //count the pixels
byte blue = p[0];
byte green = p[1];
byte red = p[3];
int pixelValue = System.Drawing.Color.FromArgb(0, red, green, blue).ToArgb();
total += pixelValue;
double average = total / count;
totalVariance += Math.Pow(pixelValue - average, 2);
standardDeviation = Math.Sqrt(totalVariance / count);
//go to next pixel
p += 3;
}
}
bmp.UnlockBits(bmpData);
return standardDeviation;
}
wpf打印控件 实现分页打印控件功能的更多相关文章
- 使用ScriptX控件实现IE浏览器分页打印功能
之前讲过js调用ie浏览器自带打印的用法,今天讲使用插件的方式.浏览器自带打印不能控制页边距.页眉页脚等选项,尤其是如果分页打印的话,无法自动将前一页标题带到本页,所以不适用多页打印的功能.使用Scr ...
- lodop 控件实现web打印功能
WEB套打可选方案不多,理想的更少,利用免费控件Lodop+JavaScript实现精确套打,算是较为经典的选择.这种方案其实比较简单,利用一个htm文件就可以实现模板设计过程,几乎是“空手套”式的开 ...
- c# asp.net 鼠标改变控件坐标位置,更改控件坐标,注册表保存读取,打印,查找局域网内打印机等等收集
界面虽然被我弄的很难看,但功能还可以 里边注册表的路径自己设置一下,或者加一个创建注册表的语句,不然会报错 前台: <%@ Page Language="C#" AutoEv ...
- WPF MVVM 用户控件完成分页
项目中经常会有分页查询的情况,在WPF中我们可以通过用户控件完成分页 一下为分页控件的页面代码, <UserControl x:Class="Foundation.UCtrl.Next ...
- 关于使用smsx.cab控件做web打印使用方法(转)
注意:在使用之前先告诉下我的痛苦经历 在做WEB项目是我的JSP页面在jsp文件夹里,我把smsx.cab放在js文件夹里(jsp和js是用级别目录) 在本机上测试可以正确下载控件,但是部署到测试服务 ...
- 基于WPF系统框架设计(10)-分页控件设计
背景 最近要求项目组成员开发一个通用的分页组件,要求是这个组件简单易用,通用性,兼容现有框架MVVM模式,可是最后给我提交的成果勉强能够用,却欠少灵活性和框架兼容性. 设计的基本思想 传入数据源,总页 ...
- WPF知识点全攻略05- XAML内容控件
此处简单列举出布局控件外,其他常用的控件: Window:WPF窗口 UserControl:用户控件 Page:页 Frame:用来浏览Page页 Border:嵌套控件,提供边框和背景. Butt ...
- WPF基础知识、界面布局及控件Binding(转)
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- 036. asp.netWeb用户控件之五使用用户控件实现分页数据导航
UserDataPager.ascx用户控件代码: <%@ Control Language="C#" AutoEventWireup="true" Co ...
随机推荐
- 转:SQL Server 批量插入数据的两种方法
在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量 ...
- GridView控件显示图片
与图片的二进制数据库存储和显示 1.将图片以二进制存入数据库 2.读取二进制图片在页面显示 3.设置Image控件显示从数据库中读出的二进制图片 4.GridView中ImageField以URL方式 ...
- svn 如何解决冲突
项目中,往往不止你一人开发,多人开发,难免会有代码的冲突.彼此间谁也不能保证不会修改同个文件.如果修改了同个方法的内容.这时提交到svn是会提示代码冲突的. 当然,冲突是可控的,但不能避免.每次写代码 ...
- SCOM随笔
1.在监控群集资源时,安装完agent后,在代理管理-agent属性中选中“允许此代理充当代理并发现其他计算机上的托管对象” 如果监控DC的话,也要选中该选项
- javax.naming.NameNotFoundException:Name[ XXX] is not bound in this context.
在用局部数据源去连数据库的时候,在本地的项目中,都是可以的,可是一部署到服务器上,就报错了. 报的错误是:javax.naming.NameNotFoundException:Name[ XXX] i ...
- Files to be needed by importing the android application with eclipse
1. AndroidManifest.xml 2. project.properties # This file is automatically generated by Android Tools ...
- 使用air进行移动app开发常见功能和问题(二)
1. Air如何判断android.ios 平台网络连接状态? Android,使用as3原生api: if(NetworkInfo.isSupported)//只有android支持 Networ ...
- 面向对象的程序设计(二)理解各种方法和属性typeof、instanceof、constructor、prototype、__proto__、isPrototypeOf、hasOwnProperty
//理解各种方法和属性typeof.instanceof.constructor.prototype.__proto__.isPrototypeOf.hasOwnProperty. //1.typeo ...
- [面试算法题重做]求1+2+...+n
题目:求1+2+…+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句(A?B:C). 不能用条件语句,基本上只有考虑递归. 常规解法: 利用构 ...
- Ruby简介,附带示例程序
Ruby语言是日本人松本行弘于1993年器开始着手研发,经历2年时间,发布了Ruby语言的第一个版本:0.95版. Ruby是一种非常简介的解释性语言,一种纯粹的面向对象编程语言,甚至比Jav ...