Document with mutiple sheets

Any suggestions on how best implement a document with multiple sheets ?

The sheets are limited in size to ensure readable printing to regular size paper at a reasonable scale. There could be thousands of sheets in a single document.
Layers don't seem the right way to deal with this. Or are they ?
Should the sheets be implemented as regions on a (large) single canvas ?
Or is there a way to create a container document for a collection of sub-documents each representing a sheet ?

Is there supposed to be any relationship between objects on different “sheets”? I’m asking about seeing multiple sheets in the same Control simultaneously, or expected relative Positions, or links visually connecting objects on different sheets, or being able to rubber-band select objects from different sheets in one operation, or anything else that would require the sheets to be in the same GoDocument?

I think using separate GoDocuments would make the most sense. This is done moderately commonly. For printing, you can easily implement a custom PrintController that prints multiple documents.
But if you need to have everything simultaneously in one GoView (and thus in one GoDocument) that's OK too. You can create as many GoSheets as you want, and position each set of objects appropriately. And again, it's easy to define a different custom PrintController that prints a collection of sheets.

Here’s code for implementing a PrintController that prints a bunch of sheets, as defined by the locations of a collection of GoSheets.

[code] /* USE:
PrintDocument pd = new PrintDocument();
pd.DocumentName = "Multiple sheet test";
pd.PrintController = new MultiSheetPrintController(goView1.Document, goView1.BackgroundLayer);
public class SheetPrintingView : GoView {
public SheetPrintingView() {}
private GoSheet myPrintSheet = null;
public GoSheet PrintSheet {
get { return myPrintSheet; }
set { myPrintSheet = value; }
public override PointF PrintDocumentTopLeft {
get {
if (this.PrintSheet != null)
return this.PrintSheet.MarginBounds.Location;
return base.PrintDocumentTopLeft;
public override SizeF PrintDocumentSize {
get {
if (this.PrintSheet != null)
return this.PrintSheet.MarginBounds.Size;
return base.PrintDocumentSize;
public override float PrintScale {
get { return 1; }
public class MultiSheetPrintController : StandardPrintController {
public MultiSheetPrintController(GoDocument document, IGoCollection sheets) {
myDocument = document;
mySheets = sheets;
private GoDocument myDocument = null;
private IGoCollection mySheets = null;
private int mySheetIndex = 0;
private ArrayList mySheetArray = null;
private PrintPageEventHandler myPrintPageHandler = null;
public override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e) {
SheetPrintingView view = new SheetPrintingView();
view.Document = myDocument;
view.PrintSheet = (GoSheet)mySheetArray[mySheetIndex];
myPrintPageHandler = new PrintPageEventHandler(view.PrintDocumentPage);
document.PrintPage += myPrintPageHandler;
return base.OnStartPage(document, e);
public override void OnEndPage(PrintDocument document, PrintPageEventArgs e) {
e.HasMorePages = (mySheetIndex < mySheetArray.Count);
base.OnEndPage(document, e);
document.PrintPage -= myPrintPageHandler;
public override void OnStartPrint(PrintDocument document, PrintEventArgs e) {
mySheetIndex = 0;
mySheetArray = new ArrayList();
foreach (GoObject obj in mySheets) {
GoSheet sheet = obj as GoSheet;
if (sheet != null) {
if (mySheetArray.Count == 0) {
e.Cancel = true; //??? doesn't work
base.OnStartPrint(document, e);

Thanks for the reply.

The sheets are not graphically linked, but do refer to one another in a textual way.
The editor needs to traverse all the sheets in a 'document' to produce output.
Also, the user needs to be able to navigate all the sheets (e.g. through a sheet browse tree) and ideally have more than one sheet open at the same time.
Each sheet can be open in a separate window (sheet do not need to be combined in a single view).
Will the collection of documents you are eluding to work for this ?

It sounds like you could implement it either way. Will any object extend beyond the extent of a sheet?

No object would be extended over multiple sheets.

OK, you can do either either way. I think using a separate GoDocument for each sheet would probably be easiest for you to implement and to manage. You’ll just need code for dealing with multiple documents when loading/storing and when printing. The code above isn’t right for your purposes, but I hope will give you an idea for how a custom PrintController can be implemented.

There is a similar requirement for me where I need to show multiple sheets in a view linked to one single document.

Could you please tell me how to create multiple sheets and show the same.

Actually I need to implement similar design how an IE7 where we can have multiple tab views and also multisheets view in a single tab.

I have a question related to this post, but deals with objects snapping to grid of multiple sheets.

I’ve created a view with multiple sheets added to the backgroundlayer.

Each sheet has a GoGrid that objects should snap to.

The objects are added to the view’s document, but when dragged around they only snap to the the last added sheet.

Seems like the SnapPoint function traverses backwards on the backgroundlayer to find the closest snappoint.

Anyhow I did a override of the SnapPoint function and it fixed my problem.

I just wanted to confirm if this was the default behavior with multiple sheets. Or if there is a better way to do this.


Each GoSheet has a GoGrid whose GoGrid.SnapOpaque property is true, by default.

So if your sheets are overlapping, objects will only be snapped to the grid of the sheet at which the mouse is.

But if you are creating your own GoGrids, the behavior will depend on their values of GoGrid.SnapOpaque and their extents.

The sheets do no overlap and they are all the same size and SnapOpaque is true.

This is what I did in the override of SnapPoint:

public override PointF SnapPoint(PointF p, GoObject obj)
foreach (GoObject gobj in this.BackgroundLayer)
GoSheet sheet = gobj as GoSheet;
if (sheet != null && sheet.Bounds.Contains§)
return sheet.Grid.FindNearestGridPoint(p, obj);
return base.SnapPoint(p, obj);