收据打印机上的 WPF PrintVisual 正在剪切图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15117280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF PrintVisual on receipt printer is clipping image
提问by DermFrench
I'm printing a visual in WPF to a receipt printer (Star TSP 700II). When the visual is small it is fine and it prints okay.
我正在将 WPF 中的视觉效果打印到收据打印机 (Star TSP 700II)。当视觉效果很小时,它很好并且打印正常。
However when the visual grows it will clip the image and it prints to a certain size on the roll in the Star printer and then it just cuts without printing the remainder of the image.
然而,当视觉增长时,它会剪裁图像,并在 Star 打印机的卷筒上打印到特定尺寸,然后它只是剪切而不打印图像的其余部分。
PrintDialog.PrintVisual(Grid1, "Test");
I've tried adjusting the PageMediaSize but that is not changing anything on the printout.
我试过调整 PageMediaSize 但这并没有改变打印输出的任何内容。
Interesting when I print to Microsoft XPS Document Writer the saved file has the full image.
有趣的是,当我打印到 Microsoft XPS Document Writer 时,保存的文件具有完整图像。


I've also noticed the size it prints to is always maximum height = height of an A4 page. Question is how to I get it to print past the height of an A4 (when I print a test document from the printer preferences it is able to do this).
我还注意到它打印的尺寸总是最大高度 = A4 页面的高度。问题是如何让它打印超过 A4 的高度(当我从打印机首选项打印测试文档时,它能够做到这一点)。
回答by DermFrench
Ok I solved this using following class. Basically I put what I want to print inside a scrollviewer and put a stackpanel inside that, then pass this stackpanel to my print helper and it now prints without clipping:
好的,我使用以下课程解决了这个问题。基本上我把我想打印的东西放在一个滚动查看器里面,然后在里面放一个堆栈面板,然后把这个堆栈面板传递给我的打印助手,它现在可以打印而不剪裁:
public static class PrintHelper
{
public static FixedDocument GetFixedDocument(FrameworkElement toPrint, PrintDialog printDialog)
{
var capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
var pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
var visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
var fixedDoc = new FixedDocument();
//If the toPrint visual is not displayed on screen we neeed to measure and arrange it
toPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
toPrint.Arrange(new Rect(new Point(0, 0), toPrint.DesiredSize));
//
var size = toPrint.DesiredSize;
//Will assume for simplicity the control fits horizontally on the page
double yOffset = 0;
while (yOffset < size.Height)
{
var vb = new VisualBrush(toPrint)
{
Stretch = Stretch.None,
AlignmentX = AlignmentX.Left,
AlignmentY = AlignmentY.Top,
ViewboxUnits = BrushMappingMode.Absolute,
TileMode = TileMode.None,
Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height)
};
var pageContent = new PageContent();
var page = new FixedPage();
((IAddChild)pageContent).AddChild(page);
fixedDoc.Pages.Add(pageContent);
page.Width = pageSize.Width;
page.Height = pageSize.Height;
var canvas = new Canvas();
FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
canvas.Width = visibleSize.Width;
canvas.Height = visibleSize.Height;
canvas.Background = vb;
page.Children.Add(canvas);
yOffset += visibleSize.Height;
}
return fixedDoc;
}
public static void ShowPrintPreview(FixedDocument fixedDoc)
{
var wnd = new Window();
var viewer = new DocumentViewer();
viewer.Document = fixedDoc;
wnd.Content = viewer;
wnd.ShowDialog();
}
public static void PrintNoPreview(PrintDialog printDialog,FixedDocument fixedDoc)
{
printDialog.PrintDocument(fixedDoc.DocumentPaginator, "Test Print No Preview");
}
}
回答by DeMama
The last few days i also had this problem.
最近几天我也遇到了这个问题。
The solution was to render the root element in memory.
解决方案是在内存中渲染根元素。
PrintDialog dlg = new PrintDialog();
// Let it meassure to the printer's default width
// and use an infinity height
Grid1.Meassure(new Size(dlg.PrintableAreaWidth, double.PositiveInfinity));
// Let it arrange to the meassured size
Grid1.Arrange(new Rect(Grid1.DesiredSize));
// Update the element
Grid1.UpdateLayout();
Then create a new papersize for the printer to use:
然后为打印机创建一个新的纸张尺寸以使用:
You should check your printer's cut settings (e.g use Receiptcutting mode).
您应该检查打印机的切割设置(例如使用Receipt切割模式)。
// Create a new papersize with the printer's default width, and the Grids height
dlg.PrintTicket.PageMediaSize
= new PageMediaSize(dlg.PrintableAreaWidth, Grid1.ActualHeight);
// Let's print !
dlg.PrintVisual(Grid1, "blah");
This works like a charm for me, and saved me lots of code.
这对我来说就像一个魅力,并为我节省了大量代码。
As receipt printer's don't need pagination, I think this is very easy to use.
由于不需要收据打印机pagination,我认为这很容易使用。
Note that I NOTuse this method for rendering an UIElementcreated in XAML, it's all made in code with a StackPanelas root element.
请注意,我不使用此方法来呈现UIElement在 XAML 中创建的对象,它都是在代码中使用StackPanel作为根元素创建的。
回答by Luis Tellez
You are using PrintDialog.PrintVisual which is only supposed to print what you can see. For multi-page results you would need to do more.
您正在使用 PrintDialog.PrintVisual 它只应该打印您可以看到的内容。对于多页结果,您需要做更多的工作。
You could try the DocumentPaginator http://msdn2.microsoft.com/en-us/library/system.windows.documents.documentpaginator.aspx
你可以试试 DocumentPaginator http://msdn2.microsoft.com/en-us/library/system.windows.documents.documentpaginator.aspx
or
或者
PrintDialog.PrintDocument http://msdn2.microsoft.com/en-us/library/system.windows.controls.printdialog.printdocument.aspx.
PrintDialog.PrintDocument http://msdn2.microsoft.com/en-us/library/system.windows.controls.printdialog.printdocument.aspx。

