Sunday, July 4, 2010

[Revit API] Document.PrintManager returns a new instance every time

A gotcha that you may run into if you use the Print API in Revit is that the PrintManager property of a Document always returns a NEW PrintManager.
So if you make a change (say to the print range) of Document.PrintManager directly, it will be pointless.
Document.PrintManager.PrintRange = PrintRange.Select;
//then submit print

both will act on a NEW PrintManager each time, which isn’t what you want. What you need to do is maintain a reference to PrintManager yourself, only calling Document.PrintManager once.
PrintManager manager = Document.PrintManager;
manager.PrintRange = PrintRange.Select;

If you have a look using Red Gate’s .NET Reflector to disassemble that method in the RevitAPI.dll, you can see why:
public unsafe PrintManager get_PrintManager()
    PrintManager manager;
    REVIT_MAINTAIN_STATE revit_maintain_state;
        manager = new PrintManager(this);
        ___CxxCallUnwindDtor(REVIT_MAINTAIN_STATE.{dtor}, (void*) &revit_maintain_state);
    return manager;

As convenient as only passing around the Document object is, it’s not going to work! Changes made to one instance are not likely to apply to any others.


Piotr Zurek said...

OMG! Thanks for that. I've lost 2 days completely stuck, thinking it's a bug.

Matt Mason said...

Rod - thankfully I only wasted an hour or so before I decided to look around for this...