Using FlowDocument XAML to print XPS Documents. (Part 3)
Introduction
Welcome to Part 3 of the Using FlowDocument XAML to print XPS Documents. This article will demonstrate altering the page size of the FlowDocument. I will be building off of the classes used in Part 2 of this series.
Altering PageSize of a FlowDocument.
First, we need to extend our XPS creation class by adding a page size adjustment method.
public static DocumentPaginator AdjustFlowDocumentToPage(DocumentPaginator document, PrintQueue printQueue)
{
const double inch = 96;
PrintTicket printTicket = printQueue.UserPrintTicket;
// Get the media size.
double width = printTicket.PageMediaSize.Width.Value;
double height = printTicket.PageMediaSize.Height.Value;
// Set the margins.
double leftmargin = 1.25 * inch;
double rightmargin = 1.25 * inch;
double topmargin = 1 * inch;
double bottommargin = 1 * inch;
// Calculate the content size.
double contentwidth = width - leftmargin - rightmargin;
double contentheight = height - topmargin - bottommargin;
document.PageSize = new Size(contentwidth, contentheight);
return document;
}
This method pretty much identifies the page size of the print queue source you are using and adjusts the DocumentPaginator page size to fit. Nothing too special here.
**One warning though, you will want to make certain the contentwidth and the contentheight are both positive numbers. I excluded the tests here for simplicity **
Using the new AdjustFlowDocumentToPage method.
Now all that is left to do is to use the new method when we print.
private void PrintFuelingButton_Click(object sender, RoutedEventArgs e)
{
SampleClass sample = new SampleClass();
sample.Sample = "FlowDocument DataBinding Sample";
IDocumentPaginatorSource flowDocument =
XamlTemplatePrinter.RenderFlowDocumentTemplate(Path.Combine(Environment.CurrentDirectory, "XamlDocumentTemplate.xaml"), sample);
PrintDialog flowPrintDialog = XamlTemplatePrinter.GetPrintDialog();
if (flowPrintDialog == null)
return;
PrintQueue flowPrintQueue = flowPrintDialog.PrintQueue;
// This line is new and is an easy way to resize the PageSize.
// However, it isn't enough just to change the PageSize, you also want to account for margin.
flowDocument.DocumentPaginator.PageSize = new Size(96 * 8, 96 * 11);
// Print the FlowDocument, but check for the PrintQueue PageSize and adjust the content.
XamlTemplatePrinter.PrintFlowDocument(flowPrintQueue,
XamlTemplatePrinter.AdjustFlowDocumentToPage(flowDocument.DocumentPaginator, flowPrintQueue));
}
Please feel free to comment or leave suggestions for future articles.
I tried this out and the margins don’t seem to apply. The text still prints at position 0,0. Am I missing something?
Thanks!
I had the same problem and solved it by using the PagePadding property of the FlowDocument class. Below is my attempt to paste the re-written method (note that Inch is a constant I defined in the class):
private static DocumentPaginator FitToPage(FlowDocument document, PrintQueue printQueue)
{
// Initialize method variables
PrintTicket printTicket = printQueue.UserPrintTicket;
DocumentPaginator documentPaginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
// Set margins
double xMargin = (1.25 * Inch);
double yMargin = (1 * Inch);
// Set the page size
documentPaginator.PageSize = new Size(8.5 * Inch, 11 * Inch);
// Set the page padding
document.PagePadding = new Thickness(yMargin, xMargin, xMargin, yMargin);
return documentPaginator;
}