Skip Navigation LinksHome / Articles / View Article

A look at the Printing API in Silverlight 4

+ Add to SilverlightShow Favorites
10 comments   /   posted by Corey Schuman on Nov 26, 2009
(5 votes)
Categories: Learn , Tutorials , Samples

With the addition of the much anticipated Printing API, Silverlight continues to round out its feature set. Although beta, it’s very flexible enabling you to print what you see on screen, selected portions of the UI, custom “print-friendly” views, and multiple page printing.

This post takes a deep dive into the Printing API, starting out with a simple scenario and moving to the more complex.

Print what you see

To get up and running quickly, create a simple UI. The below figure shows a sample contact screen with text fields, an image, and a print Button.

clip_image002

Printing the UI, exactly as it appears on screen, add a Click event handler to handle the printing of the document. PrintDocment is the engine of printing. The below block of code shows a simple print job. The items of note are:

  • Create a new PrintDocument
  • Give the print job a name using DocumentName. This name is displayed in the print queue and is optional.
  • Implement the PrintPage event handler. Set PageVisual to the UIElement you want to print. In this case it is the whole UserControl.
  • Finally call Print() to open the Print Dialog box.

clip_image004

C# in text format

void PrintButton_Click(object sender, RoutedEventArgs e)
{
    // Create new a new PrintDocument object
    PrintDocument pd = new PrintDocument();
    
    // Give the document a name that's displayed in the printer queue
    pd.DocumentName = "Silverlight 4 - Test print job";
    
    // Set the printable area
    pd.PrintPage += (s, args) =>
    {
        args.PageVisual = this;
    };
    
    // Print the document
    pd.Print();
}

When the Print() method is called the user is prompted with the familiar print dialog box, shown below. Clicking Print fires the StartPrint event then for each page that needs to print PrintPage event is fired.

clip_image006

The PrintDocument

So far, DocumentName, PrintPage, and Print() have been used from the PrintDocument. What else is there? As always, you can take a look at the MSDN page for the complete list of members, however here are the main methods and events that you need to know about:

  • DocumentName – Property defining the name of the print job.
  • Print() – Prints the document
  • PrintPage – Event fired before the printing of each page. If you print multiple pages then this event fires for each page.
  • EndPrint – Event fired when the printing is either completed or cancelled.
  • StartPrint – Event fired after the user clicks Print on the print dialog box but before the PrintPage
  • HasMorePages – Part of the PrintPageEventArgs, the arguments passed into PrintPage, informing whether or not there are more pages to print.

Custom "print-friendly" page

Reporting is a natural scenario where printing is crucial. I remember when programming in ASP.NET and spending hours upon hours in Crystal Reports trying to get a report to look exactly right. Fortunately you won’t have to do that with Silverlight 4; you can simply create two views with the same DataContext (think MVVM) and create two separate UI’s (one for to display and one to print).

Taking the above UI and adding TextBlocks as well as TextBoxes you can create a printer friendly page. Instead of showing lengthy Xaml, here’s how the UI looks in Blend.

clip_image008

When the UI is rendered the Visibility of PrintTextPanel is set to Collapsed and InputBoxesPanel is Visible. The code needs to be modified to toggle the visibility when printed. In the modified code below, take note that the in PrintPage the visibility of the Panels are toggled, and an EndPrint event is registered to toggle the visibility back.

clip_image010 

void PrintButton_Click(object sender, RoutedEventArgs e)
{
    // Create new a new PrintDocument object
    PrintDocument pd = new PrintDocument();
    
    // Give the document a name that's displayed in the printer queue
    pd.DocumentName = "Silverlight 4 - Test print job";
    
    // Set the printable area
    pd.PrintPage += (s, args) =>
    {
        this.InputBoxesPanel.Visibility = Visibility.Collapsed;
        this.PrintTextPanel.Visibility = Visibility.Visible;
        args.PageVisual = this.PrintablePanel;
    };
    
    pd.EndPrint += (s, args) => 
    {
        this.InputBoxesPanel.Visibility = Visibility.Visible;
        this.PrintTextPanel.Visibility = Visibility.Collapsed;
    };
    
    // Print the document
    pd.Print();
}

Finally, the document is printed without a background and without TextBlocks.

clip_image012

Share


Comments

Comments RSS RSS
  • RE: A look at the Printing API in Silverlight 4  

    posted by Alex on Nov 26, 2009 12:19
    Nice батенце nice :)
  • RE: A look at the Printing API in Silverlight 4  

    posted by Abbot on Nov 30, 2009 11:18
    Me like... :-)
  • RE: A look at the Printing API in Silverlight 4  

    posted by anjumkml on Apr 08, 2010 10:47
    also can print crystal report as such way?
  • RE: A look at the Printing API in Silverlight 4  

    posted by Zareth on Apr 22, 2010 10:47
    What appen if the user just press "Cancel" in the dialogbox of print, because to me it's not working...
  • RE: A look at the Printing API in Silverlight 4  

    posted by Braulio on May 08, 2010 11:53
    Update to RTW would be nice, including some additional topics like how to handle paper size, dpi's...
  • RE: A look at the Printing API in Silverlight 4  

    posted by Braulio on May 08, 2010 11:58

    Once readed this good article an appropiate one for further reading:

    http://www.davidpoll.com/2010/04/16/making-printing-easier-in-silverlight-4/

  • RE: A look at the Printing API in Silverlight 4  

    posted by Fred Derf on May 11, 2010 23:15

    Everyone on the 'net doesn't see the RTW object model for PrintDocument:

    No more DocumentName property, it's a param to the Print method now. 

    Plus new BeginPrint

    namespace System.Windows.Printing
    {
        // Summary:
        //     Provides printing capabilities for a Silverlight application.
        public class PrintDocument : DependencyObject
        {
            // Summary:
            //     Gets the identifier for the System.Windows.Printing.PrintDocument.PrintedPageCount
            //     dependency property.
            //
            // Returns:
            //     The identifier for the System.Windows.Printing.PrintDocument.PrintedPageCount
            //     dependency property.
            public static readonly DependencyProperty PrintedPageCountProperty;

            // Summary:
            //     Initializes a new instance of the System.Windows.Printing.PrintDocument class.
            public PrintDocument();

            // Summary:
            //     Gets the number of pages that have printed.
            //
            // Returns:
            //     The number of pages that have printed.
            public int PrintedPageCount { get; }

            // Summary:
            //     Occurs after the System.Windows.Printing.PrintDocument.Print() method is
            //     called and the print dialog box successfully returns, but before the System.Windows.Printing.PrintDocument.PrintPage
            //     event is raised.
            public event EventHandler<BeginPrintEventArgs> BeginPrint;
            //
            // Summary:
            //     Occurs when the printing operation is complete or when the print operation
            //     is cancelled by the application author.
            public event EventHandler<EndPrintEventArgs> EndPrint;
            //
            // Summary:
            //     Occurs when each page is printing.
            public event EventHandler<PrintPageEventArgs> PrintPage;

            // Summary:
            //     Starts the printing process for the specified document by opening the print
            //     dialog box.
            //
            // Parameters:
            //   documentName:
            //     The name of the document to print.
            //
            // Exceptions:
            //   System.Security.SecurityException:
            //     The print operation is not user-initiated.
            [SecuritySafeCritical]
            public void Print(string documentName);
        }
    }

  • RE: A look at the Printing API in Silverlight 4  

    posted by Apoorv on Jun 14, 2010 20:12

    I am getting the following error

    {System.Security.SecurityException: Dialogs must be user-initiated.
       at System.Windows.Printing.PrintDocument.Print(String documentName)
       at McKesson.PPS.Fusion.UI.Module.Encounter.Views.SearchEncounterView.btnPrint_Click(Object sender, RoutedEventArgs e)
       at System.Windows.RoutedEventHandler.Invoke(Object sender, RoutedEventArgs e)
       at System.Windows.Controls.Primitives.ButtonBase.OnClick()
       at System.Windows.Controls.Button.OnClick()
       at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
       at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)
       at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)}

  • RE: A look at the Printing API in Silverlight 4  

    posted by SLNoob on Jul 09, 2010 16:38
    @Apoorv: remove debug breakpoints from btnPrint_Click and printpage event handler, this is a "timing" problem (.NET refuses request after some wait time).
  • RE: A look at the Printing API in Silverlight 4  

    posted by Johnny on Jul 14, 2010 16:00

    How can print any grid?

Add Comment

 
 

   
  
  
   
Please add 5 and 1 and type the answer here:

Join the free SilverlightShow webcast 'Running Silverlight Outside the Browser and with Elevated Trust'. Sept 7th, 8 am - 9 am PDT.
In this live session Chris Anderson will cover configuring and debugging OOB mode, toast notifications, elevated trust, direct file access and much more.
Learn more | Register | See more webinars (hide this)