打印多页WPF控件,在一行数据上没有分页
本文关键字:数据 一行 分页 WPF 控件 打印 | 更新日期: 2023-09-27 18:18:34
我制作了一个发票,它的底部有一个listview来列出所有的行项目。这可以在一个页面标记上运行,所以我重载了DocumentPaginator类以允许我打印多个页面。但是,有时它会在列表视图的一行中间剪切页面。我发现一篇文章使用wpf控件的位图,然后检查一行像素的颜色以确定是否有空白或数据(下面的代码)。但是,当我将控件制作成位图时,间距和行高与我将wpf控件打印为xps或打印到打印机时不同。关于如何智能地分割页面或使位图与xps匹配,还有其他想法吗?
private void GetGoodCut()
{
int goodCut = _lastCut;
int lastNumber = 0;
int numberCount = 1;
// At most, it will take 32 pixel lines to find a white space
for (int i = 0; i < 32; i++)
{
int number = rowPixelWhiteCount(_bitmap, goodCut);
goodCut--;
if (number == lastNumber)
{
numberCount++;
// White space count between LV lines is 12
if (numberCount == 12)
{
lastNumber = i - 6;
break;
}
}
else
{
// If we started inside a white space, can break if starting before/at middle of the white space
if (numberCount > 5)
{
lastNumber = i - 6;
break;
}
numberCount = 1;
}
lastNumber = number;
}
_lastCut -= lastNumber;
}
private int rowPixelWhiteCount(System.Drawing.Bitmap bmp, int row)
{
int colorCount = 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++)
{
// Printing in black/white, look for non-black pixels
byte blue = p[0];
byte red = p[1];
byte green = p[3];
if (blue > 0 && red > 0 && green > 0)
colorCount++;
// go to next pixel
p += 3;
}
}
bmp.UnlockBits(bmpData);
count.Add(colorCount);
return colorCount;
}
我相信从WPF应用程序打印多个页面的秘诀是使用多个FixedDocument
元素…您也可以在此过程中使用DocumentPaginator
元素。由于这在网上有很好的记录,我在这里不再赘述。相反,请参阅NBD Tech网站上的WPF打印第2部分-固定文档页面了解完整的故事。
作为额外的帮助,您还可以参考Abhishek Shukla网站上的高级WPF第2部分(5):在Windows演示文稿基础中打印页面。
最后,如果所有这些都失败了,您可能会对使用WPF打印引擎:第一部分中的代码项目感兴趣。