Click here to Skip to main content
Click here to Skip to main content

Tagged as

Setting Printer Paper Size From Silverlight Application

, 11 Mar 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
Tips to control printer setting without printdialog in Silverlight

Introduction

Consider a drawing tool written in Silverlight, which accepts the paper size of the drawing area (e.g. A3). At the time of printing, many times users do not want to change the default printer setting again as they already provided paper size for drawing area and now they need to use this size for paper-size of printer (A3 which is set by user). User wants application to change the printer setting according to drawing area paper-size. Hiding interaction of user with PrintDialog and allow the "Silent" printing experience in Silverlight involves security risk.

Background

Silverlight provides its own PrintDocument class for printing, though it does not allow access to printer setting such as paper size, margin, etc. After calling Print method of PrintDocument, Silverlight opens PrintDialogBox, which asks user for document setting.

Sometimes users do not want to interact with PrintDialog. User wants application to set the default paper size and print the document. This requirement is not straight forward in Silverlight, and requires some work around. From trusted Silverlight application, we can call COM InterOp DLL to achieve this.

The article explains how to print in Silverlight without PrintDialog and set paper size automatically.

Using the Code

The below code creates a C# COM-InterOp library which exposes Print method and SetPaperSize method. Print method prints the document; SetPaperSize sets the default paper size for the document. The class accepts byte array of an image to be printed, you can pass byte array of WritableBitmap here.
The simple steps shown below instruct how to create, deploy and use the COM-interop library from Silverlight.

  1. Create Windows Form Control library in VS 2010.
  2. Create a class PrinterController. Mark it with ClassInterfaceAttribute,ComVisibleAttribute,ProgIdAttribute.
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [ComVisible(true)]<
    [ProgId("PrinterController")]
    public class PrinterController
  3. Add the necessary methods inside this class which accept printer page settings.
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [ComVisible(true)]
    [ProgId("PrinterController")]
    public class PrinterController 
    {
     	private PrintDocument doc;
    	private Image image;
    	private PaperSize paperSize;
    /// <summary>
    /// Initializes a new instance of the <see cref="PrinterController"/> class.
    /// </summary>
    public PrinterController()
    {
    	doc = new PrintDocument();
    	doc.PrintPage += new PrintPageEventHandler(doc_PrintPage); 
    	doc.EndPrint += new PrintEventHandler(doc_EndPrint); 
    }
    
    /// <summary>
    /// Handles the EndPrint event of the doc control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Drawing.Printing.PrintEventArgs"/> 
    /// instance containing the event data.</param>
    void doc_EndPrint(object sender, PrintEventArgs e)
    {
    	doc.PrintPage -= new PrintPageEventHandler(doc_PrintPage);
    	doc.EndPrint -= new PrintEventHandler(doc_EndPrint); 
    	image.Dispose();
    	doc.Dispose(); 
    }
    
    public void IsLandScapeMode(bool islandscape)
    {
    	doc.DefaultPageSettings.Landscape = islandscape;
    	doc.PrinterSettings.DefaultPageSettings.Landscape = islandscape;
    }
    
    /// <summary>
    /// Sets the size of the paper.
    /// </summary>
    /// <param name="paperSizeName">Name of the paper size.</param>
    public void SetPaperSize(string paperSizeName)
    {
    	paperSize = doc.PrinterSettings.PaperSizes.Cast<PaperSize>().FirstOrDefault
              (a => a.PaperName.Equals(paperSizeName, 
    		StringComparison.InvariantCultureIgnoreCase));
    	if(paperSize==null)
    	throw new ArgumentException(string.Format
    		("Papersize {0} not found.",paperSizeName));
    	doc.DefaultPageSettings.PaperSize = paperSize;
    	doc.PrinterSettings.DefaultPageSettings.PaperSize = paperSize;
    }
    /// <summary>
    /// Sets the printing image.
    /// </summary>
    /// <param name="data">The data.</param>
    public void SetPrintingImage(byte[] data)
    {
    	using (MemoryStream stream = new MemoryStream())
    	{
    		stream.Write(data, 0, data.Length);
    		image = Image.FromStream(stream);
    	}
    }
    
    /// <summary>
    /// Prints this instance.
    /// </summary>
    public void Print()
    { 
    	doc.Print();
    }
    
    /// <summary>
    /// Handles the PrintPage event of the doc control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Drawing.Printing.PrintPageEventArgs"/> 
    /// instance containing the event data.</param>
    void doc_PrintPage(object sender, PrintPageEventArgs e)
    {
    	e.PageSettings.PaperSize = paperSize;
    	e.PageSettings.PrinterSettings.DefaultPageSettings.PaperSize = paperSize;
    	e.Graphics.DrawImage(image, doc.PrinterSettings.DefaultPageSettings.Bounds);
    } 
    }
  4. Check Register for COM interop in project properties.
  5. Deploy this DLL on client machine using regasm tool.
    In Silverlight application, where printing is required, create PrinterController object using the following method:
    dynamic obj = AutomationFactory.CreateObject("PrintController")
  6. The Silverlight application uses this interop to set up papersize and printing as follows:
    dynamic obj = AutomationFactory.CreateObject("PrinterController"); 
    
    ImageTools.Image image = this.ToImage();
    StreamWriter reader = new StreamWriter(()
    using (MemoryStream stream = new MemoryStream())
    {
    
    	IImageEncoder encoder = Encoders.GetAvailableEncoders().FirstOrDefault();
    	encoder.Encode(image, stream);
    	byte[] array = new byte[stream.Length];
    	stream.Position = 0;
    	stream.Read(array, 0, array.Length);
    
    	obj.SetPrintingImage(array);
    	obj.SetPaperSize("A3");
    }
    obj.Print();

By extending this example further, you can create your own PrintDialog in Silverlight and handle printing through it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ajit_Pudale

India India
No Biography provided

Comments and Discussions

 
QuestionI'm getting an error: Failed to create an object instance for the specified ProgID PinmemberJorgeEscobarP22-Jul-13 5:58 
AnswerRe: I'm getting an error: Failed to create an object instance for the specified ProgID PinmemberJorgeEscobarP29-Aug-13 15:04 
GeneralRe: I'm getting an error: Failed to create an object instance for the specified ProgID PinmemberMember 105692743-Feb-14 12:26 
AnswerRe: I'm getting an error: Failed to create an object instance for the specified ProgID Pinmemberdenesh kumar26-Mar-14 19:48 
GeneralMy vote of 5 PinmemberNitin Sonawane11-Mar-13 21:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150129.1 | Last Updated 12 Mar 2013
Article Copyright 2013 by Ajit_Pudale
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid