locked
HELP: How to get number of pages per sheet that will be printed. RRS feed

  • Question

  • I have an application where it is very important that I know the size of the elements I put on a printed page. All of this logic is in place and it works fine using the Printer and PrintDocument objects available in the System.Drawing.Printing namespace. Until! The printer is set to print for example 4 pages on one sheet. Then I have no idea that the size I send to printer will be reduced by a factor ~4.

    I have tried to find a way to figure out the setting for this used by the Printer.
    The Ideas I've had so far all involves using the PrintTicket.PagesPerSheet (in System.Printing) property in different ways. The closest I've gotten so far is to fetch the default print ticket from the print queue using the following code:
    public int PagesPerSheet {
        get {
            PrintQueue printQueue;
            PrintTicket printTicket = null;
    
            LocalPrintServer localPrintServer = new LocalPrintServer();
    
            // Retrieving collection of local printer on user machine
            PrintQueueCollection localPrinterCollection = localPrintServer.GetPrintQueues();
    
            System.Collections.IEnumerator localPrinterEnumerator = localPrinterCollection.GetEnumerator();
    
            while (localPrinterEnumerator.MoveNext()) {
                // Get PrintQueue from printer that matches my currently used printer
                printQueue = (PrintQueue)localPrinterEnumerator.Current;
                if (printQueue.Name == this.Name) {
                    printTicket = printQueue.DefaultPrintTicket; <----  Also tried printQueue.UserPrintTicket
                    break;
                }
            }
    
            return (printTicket != null) ? (printTicket.PagesPerSheet ?? 1) : 1;
        }
    }
    The problem with this is that I only get the default settings for the given printer and not necessarily the settings that will be used when printing my particular job.
    I can also get the current print ticket, but that is not either necessarily the settings used when printing my job.

    So to the core of the issue. How do I get a hold of the PrintTicket (or other object containing the information on the Pages per sheet setting) that will be used if I send MY print job to the printer. I thought I'd try adding a temporary empty job to the queue to get the ticket off that job and then cancel it straight away and just extract settings from the PrintTicket I got. However I cannot find a way to get the print ticket of any given job in the print queue, or even a print job I just added. The only tickets I can seem to get a hold of are the DefaultPrintTicket and the CurrentPrintTicket. Or am I missing a way to catch ticket of a job I add to the queue?

    Can you think of a way that I can use to get the information I need here? I really need help here. Thank you!!
    Wednesday, December 23, 2009 12:20 PM

Answers

  •  

    Hi Filip.  The PrintTicket should show you this information.  PrintQueue.DefaultPrintTicket.PagesPerSheet will always be 1 (unless the printer manufacturer specified some other value), and PrintQueue.UserPrintTicket.PagesPerSheet will be equal to DefaultPrintTicket.PagesPerSheet unless the user has changed the value through the Printer’s control panel.  You may also want to check the PrintCapabilities to see if PagesPerSheet is even supported by the printer.  Here is some code that shows what I am doing..

     

    Hope this helps.

     

     

    LocalPrintServer localPrintServer = new LocalPrintServer();

               

    // Get PrintQueue by name instead of enumerating through all printers

    PrintQueue printQueue = localPrintServer.GetPrintQueue("printer name");

     

    // Get the PrintCapabilities for your PrintQueue

    PrintCapabilities printCapabilities = printQueue.GetPrintCapabilities();

     

    // Get PagesPerSheetCapability.  If collection count == 0 printer does not support

    // PagesPerSheet, otherwise it will return collection of possible values.

    ReadOnlyCollection<int> ints = printCapabilities.PagesPerSheetCapability;

     

    // Get PagesPerSheet for PrintQueue.DefaultPrintTicket.

    int defaultPPS = printQueue.DefaultPrintTicket.PagesPerSheet.Value;

     

    // Get PagesPerSheet for PrintQueue.UserPrintTicket.

    // This will be == DefaultPrintTicket unless set by the user through the

    // printers control panel.

    int userPPS = printQueue.UserPrintTicket.PagesPerSheet.Value;

     

     

    Using PrintDialog

    PrintDialog printDialog = new PrintDialog();

     

    if (printDialog.ShowDialog().Value)

    {

        // Get PrintCapabilities for PrintDialog.PrintQueue.  The user can

        // modify this  through the printers control panel by clicking

        // the 'Preferences' button in the PrintDialog.

        PrintCapabilities printCapabilities = printDialog.PrintQueue.GetPrintCapabilities();

     

        // Again, the collection.Count will be == 0 if supported

        ReadOnlyCollection<int> ints = printCapabilities.PagesPerSheetCapability;

     

        // This will get the current value for PagesPerSheet from the current PrintTicket

        // being used by the PrintDialog

        int pdpps = printDialog.PrintTicket.PagesPerSheet.Value;

     }

     


    Matt Hohn
    Thursday, December 24, 2009 5:48 AM

All replies

  •  

    Hi Filip.  The PrintTicket should show you this information.  PrintQueue.DefaultPrintTicket.PagesPerSheet will always be 1 (unless the printer manufacturer specified some other value), and PrintQueue.UserPrintTicket.PagesPerSheet will be equal to DefaultPrintTicket.PagesPerSheet unless the user has changed the value through the Printer’s control panel.  You may also want to check the PrintCapabilities to see if PagesPerSheet is even supported by the printer.  Here is some code that shows what I am doing..

     

    Hope this helps.

     

     

    LocalPrintServer localPrintServer = new LocalPrintServer();

               

    // Get PrintQueue by name instead of enumerating through all printers

    PrintQueue printQueue = localPrintServer.GetPrintQueue("printer name");

     

    // Get the PrintCapabilities for your PrintQueue

    PrintCapabilities printCapabilities = printQueue.GetPrintCapabilities();

     

    // Get PagesPerSheetCapability.  If collection count == 0 printer does not support

    // PagesPerSheet, otherwise it will return collection of possible values.

    ReadOnlyCollection<int> ints = printCapabilities.PagesPerSheetCapability;

     

    // Get PagesPerSheet for PrintQueue.DefaultPrintTicket.

    int defaultPPS = printQueue.DefaultPrintTicket.PagesPerSheet.Value;

     

    // Get PagesPerSheet for PrintQueue.UserPrintTicket.

    // This will be == DefaultPrintTicket unless set by the user through the

    // printers control panel.

    int userPPS = printQueue.UserPrintTicket.PagesPerSheet.Value;

     

     

    Using PrintDialog

    PrintDialog printDialog = new PrintDialog();

     

    if (printDialog.ShowDialog().Value)

    {

        // Get PrintCapabilities for PrintDialog.PrintQueue.  The user can

        // modify this  through the printers control panel by clicking

        // the 'Preferences' button in the PrintDialog.

        PrintCapabilities printCapabilities = printDialog.PrintQueue.GetPrintCapabilities();

     

        // Again, the collection.Count will be == 0 if supported

        ReadOnlyCollection<int> ints = printCapabilities.PagesPerSheetCapability;

     

        // This will get the current value for PagesPerSheet from the current PrintTicket

        // being used by the PrintDialog

        int pdpps = printDialog.PrintTicket.PagesPerSheet.Value;

     }

     


    Matt Hohn
    Thursday, December 24, 2009 5:48 AM
  • Thank you for your reply. The capabilities is surely interesting in many other cases. I am however only interested in knowing what will be printed. I was also looking for a way to access the same information without showing a PrintDialog(). In some cases I can just change the System.Windows.Forms.PrintDialog and instead use the System.Windows.Controls.PrintDialog() instead and I can probably get the information I need.
    However I need in some cases to get this information without showing a print dialog. I might be able to get the correct properties by just instanciating the dialog without showing it. I'll try it and see what I can figure out...
    Tuesday, January 12, 2010 1:49 PM