I have the following: A wpf window with a scrollviewer and a Print button.
I am trying to print the content of the scrollviewer using the PrintDialog but it only works for xps. If I choose my printer or a document writer, then the final result is awful(half a page margin, controls cut, etc). How can I solve this issue without resizing/scaling the content of he scrollviewer?
For decent (and relatively easy) printing in WPF, you should be using a FlowDocumentScrollViewer instead of a ScrollViewer. Inside the FlowDocumentScrollViewer, you can then place a FlowDocument, which will contain the content that you want to print.
Sample XAML:
<FlowDocumentScrollViewer>
<FlowDocument PagePadding="48">
<Section>
<Paragraph>
<Run Text="sample"/>
</Paragraph>
</Section>
<Section>
<BlockUIContainer>
<my:myUserControl/>
</BlockUIContainer>
</Section>
</FlowDocument>
</FlowDocumentScrollViewer>
The 'BlockUIContainer' object is great for holding a usercontrol that can contain anything you need. The 'PagePadding' property of the FlowDocument sets the margin. 48 is equivalent to 1/2 inch. (96 dpi).
Sample print code:
Dim pd As New PrintDialog
If pd.ShowDialog Then
Dim fd As FlowDocument = docOutput
Dim pg As DocumentPaginator = CType(fd, IDocumentPaginatorSource).DocumentPaginator
pd.PrintDocument(pg, "my document")
End If
FlowDocument is probably a better solution for dynamic content and dynamic print size i.e. either is not known or may change. For my problem I knew both content and print size.
First thing I did was set the content within the ScrollViewer, a grid in my case, to A4 size which can be done easily with
<Grid x:Name="gridReport" Height="29.7cm" Width="21cm">
This means the grid maps exactly to the print area, whatever is inside the grid should not be distorted when printed.
This would still chop the top area off if the ScrollViewer was not scrolled to the top at the point of using the PrintDialog. To resolve this programmatically scroll to the top before printing with
Myscrollviewer.ScrollToTop();
PrintDialog printDialog = new PrintDialog();
if(printDialog.ShowDialog() == true)
{
printDialog.PrintVisual(gridReport, "Print Report");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With