Printing

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Sometimes you will want to add printing capabilities to your Silverlight application and not rely on the print options of the browser. For example, you may want to enable the user to print an image control that contains a map. The PrintDocument class provides the printing capability for a Silverlight application. This topic describes how to add printing capabilities to your Silverlight applications and contains the following sections:

This topic contains the following sections:

  • Showing a Print Dialog Box and Specifying Vector or Bitmap Printing

  • Performing the Print Operation

  • Set Up and Clean Up for a Print Operation

Showing a Print Dialog Box and Specifying Vector or Bitmap Printing

To add printing capabilities to your Silverlight application, you first add a PrintDocument object to the application. To show a print dialog box, you call one of the Print methods. In Silverlight 5, the method you use determines whether the print operation defaults to vector or bitmap printing. In Silverlight 4 all print operations are bitmap printing. The following table lists the print methods and describes them in more detail.

Method

Description

PrintDocument.Print

Valid for Silverlight 4 or later. Defaults to bitmap printing in Silverlight 4 and vector printing in Silverlight 5. Will fall back to bitmap printing in Silverlight 5 if a printer limitation is encountered.

PrintDocument.PrintBitmap

Valid for Silverlight 5. Forces bitmap printing.

PrintDocument.Print

Valid for Silverlight 5. Defaults to vector printing and can optionally force vector printing with the ForceVector property of the PrinterFallbackSettings parameter. You can also change the opacity of elements for vector printing purposes using the PrinterFallbackSettings.OpacityThreshold property. If vector printing is not specified, will fall back to bitmap printing if a printer limitation is encountered.

Typically, you will call one of the print methods in the event handler of a button that indicates a print operation will occur if the button is clicked. All dialog boxes in Silverlight must be user-initiated. Attempting to show the print dialog box when the operation is not user-initiated will cause a SecurityException. For example, if you attempt to show the dialog box from a Loaded event handler, a security exception will occur. In addition, there is a limit on the time allowed between when the user initiates the dialog box and when the dialog box is shown. If the time limit between these actions is exceeded, an exception will occur.

Within the print dialog box, the user can select the printer settings he or she wants and then click Print to continue the print operation or Cancel to cancel the print operation. The following illustration shows an example of the print dialog box for Windows.

Silverlight Print Dialog

Performing the Print Operation

To perform the actual print operation and specify the content to print, you must handle the PrintPage event for the PrintDocument. In the PrintPage event handler, you set the PrintPageEventArgs.PageVisual property to a UIElement that you want to print. The UIElement can be any UIElement in the application. The specified UIElement does not have to be a part of the visual tree. You set this property to a named element declared in XAML or create the UIElement you want to print. If you are creating a UIElement that contains additional elements, such as a panel that contains a list control, you should create the parent element and add all its children before setting it to the PrintPageEventArgs.PageVisual property. This enables Silverlight to calculate the layout of the element and its children for printing purposes.

To print the entire Silverlight control, you can specify the LayoutRoot element.

The following code example shows a button event handler that calls the Print method and an event handler for the PrintPage event. In this example, an Image control, which contains a map, is printed.

Partial Public Class MainPage
    Inherits UserControl
    Private pd As PrintDocument()

    Public Sub New()
        InitializeComponent()
        pd = New PrintDocument()

    End Sub

    Private Sub PrintButton_Click(ByVal sender As Object, _
            ByVal e As RoutedEventArgs)
        pd.Print("M yMap")
    End Sub

    Private Sub pd_PrintPage(ByVal sender As Object, _
            ByVal e As PrintPageEventArgs) Handles pd.PrintPage
        e.PageVisual = mapImage
    End Sub
End Class
public partial class MainPage : UserControl
{
    PrintDocument pd; 

    public MainPage()
    {
        InitializeComponent();
        pd = new PrintDocument();
        pd.PrintPage += new EventHandler<PrintPageEventArgs>(pd_PrintPage);

    }

    private void PrintButton_Click(object sender, RoutedEventArgs e)
    {
      pd.Print("My Map");
    }

    void pd_PrintPage(object sender, PrintPageEventArgs e)
    {
        e.PageVisual = mapImage;
    }
}
<StackPanel x:Name="LayoutRoot">
      <Button Margin="5" Width="200" Content="Click to print" x:Name="PrintButton" 
              Click="PrintButton_Click" />
      <Image Width="600"  Height="600" Source="RedmondMap.jpg" x:Name="mapImage"/>
  </StackPanel>

In addition to specifying the UIElement, you can get the physical size of the print area with the PrintPageEventArgs.PrintableArea property. If the UIElement exceeds the PrintableArea, the content will be clipped at the bounds of the PrintableArea. The dimensions of the printable area are in screen-based pixels.

You use the PrintPageEventArgs.HasMorePages property to print a document with multiple pages. The default for PrintPageEventArgs.HasMorePages is false, so it does not need to be set for one-page documents. However, if there are multiple pages to print, you set the PrintPageEventArgs.HasMorePages property to true to indicate that there are additional pages to print. You set PrintPageEventArgs.HasMorePages back to false in the PrintPage event handler, when the last page is being printed.

Set Up and Clean Up for a Print Operation

If you have a special set up that must be performed before the print operation occurs, handle the BeginPrint event. For example, if you want to set up a page counter for a multiple-page document, you can do this in the BeginPrint event handler.

If you have clean up that must be performed after the print operation, handle the EndPrint event. You can also use the EndPrint event handler to look for errors that occurred in the printing process by checking the Error property of the EndPrintEventArgs.

See Also

Reference