Print Preview

Would anyone be willing to share his/her print preview solution for diagrams made with GoXam? I was thinking of using the GoXam grid mechanism to draw pages to the screen.



Also, does anyone have any experience using the output from the GoXam PrintManager with Infragistics WPF Reporting/Print Preview control? I would like the output from the GoXam PrintManager to first go to the Print Preview control before going to the printer.



Sorry if these seem like novice questions, but I’m a novice. Thanks!

It might not be too hard to implement print preview in WPF, using an XPS document viewer.

An alternative might be to draw the page breaks as a grid on top of the diagram.

I don’t think any of us have experience with Infragistics reporting or print preview.

Walter,



As always, thank you for your prompt response.



The route I am pursuing regarding printing is allowing users to choose paper size, orientation, and the number of pages wide and tall. I am able to draw the pages to the screen and am able to have the diagram overlay the pages. I also set the width and height of the diagram equal to the size of the entire grid of pages. My intent would be that the users would be able to scale the diagram and move its parts around so that the diagram lays out on the grid as they prefer. I would then set the PrintManager scale to be the same as the DiagramPanel scale and print the diagram. The result should be what-you-see-is-what-you-get.



So far I have run into two problems:



1) I cannot get see to get the PrintManager scale to bind to the DiagramPanel scale.



2) Even though I am specifically setting the width and height of the diagram, parts that lie outside of the area still print, and if those parts are to the left or top of the diagram (but outside the area of the diagram panel) their printing causes a shift of the user-defined layout of parts on the pages.



Any ideas or hints would be much appreciated. Thank you!

Try something like the following:

[code] public class CustomPrintManager : PrintManager {

// the size of the printed area, inside the margins, in model coordinates;
// set this to the selected printer's DocumentPaginator.PageSize-this.Margin
public Size PrintableSize { get; set; }

// set the PrintManager.Scale as desired

// the unbound Node holding a GridPattern
private Node PrintGrid { get; set; }

public void UpdatePrintGrid() {
  if (this.PrintableSize.Width <= 0 || this.PrintableSize.Height <= 0) {
    return;  // can't update PrintGrid if we don't know printable area
  }
  if (this.PrintGrid == null) {
    this.PrintGrid = this.Diagram.PartsModel.FindNodeByKey("PrintGrid");
  }
  if (this.PrintGrid != null) {
    Rect db = this.Diagram.Panel.DiagramBounds;
    Size ps = this.PrintableSize;
    Size eps = new Size(ps.Width/this.Scale, ps.Height/this.Scale);
    // update the PrintGrid's position and size to cover the DiagramBounds
    this.PrintGrid.Location = new Point(db.X, db.Y);
    this.PrintGrid.Width = Math.Ceiling(db.Width/eps.Width)*eps.Width;
    this.PrintGrid.Height = Math.Ceiling(db.Height/eps.Height)*eps.Height;
    // update the PrintGrid's GridPattern's CellSize
    GridPattern gp = this.PrintGrid.VisualElement as GridPattern;
    if (gp != null) {
      gp.CellSize = eps;
    }
  }
}

}[/code]
Along with:

<go:Diagram x:Name="myDiagram" . . . > <go:Node Id="PrintGrid"> <go:GridPattern go:Part.LayerName="Tool" go:Part.Selectable="False"> <Path Stroke="Purple" StrokeThickness="2" go:GridPattern.Figure="HorizontalLine" /> <Path Stroke="Purple" StrokeThickness="2" go:GridPattern.Figure="VerticalLine" /> </go:GridPattern> </go:Node> </go:Diagram>
Use:

[code] myDiagram.PrintManager = new CustomPrintManager() {
PrintableSize = new Size(400, 600) //??? some bogus value for testing
};

  myDiagram.Panel.DiagramBoundsChanged += (s, e) => {
    var pm = myDiagram.PrintManager as CustomPrintManager;
    if (pm != null) pm.UpdatePrintGrid();
  };

  myDiagram.Panel.ViewportBoundsChanged += (s, e) => {
    var pm = myDiagram.PrintManager as CustomPrintManager;
    if (pm != null) {
      pm.Scale = myDiagram.Panel.Scale;
      pm.UpdatePrintGrid();
    }
  };[/code]

Walter,



I am getting a TargetInvocationException on the last two lines of code:

myDiagram.Panel.DiagramBoundsChanged += (s, e) => {…};

myDiagram.Panel.ViewportBoundsChanged += (s, e) => {…};



I am doing all of this work in a simple 1-page MainWindow application and have placed the lines referenced above in my MainWindow constructor. It’s as plain vanilla as it can be.



I apologize for not being more knowledgeable about C# coding and not being able to debug it myself.

The Diagram.Panel doesn’t exist until after the Diagram.Template has been applied, i.e. expanded.

You can refer to the Diagram.Panel, including setting up those event handlers, in a Diagram.TemplateApplied event handler.

By the way, in case it wasn’t already clear, your application will need to set the CustomPrintManager.PrintableSize according to the printer that the user has chosen.

This sample code also assumes that the current scale of the diagram (i.e. the Diagram.Panel.Scale) controls the scale at which printing will take place (i.e. the Diagram.PrintManager.Scale). That’s what I guessed that you wanted, but I’m not sure that that would be best for the typical application. If your application has some other way to specify the desired print scale, you won’t need that ViewportBoundsChanged event handler, but your code will perform the same steps in order to update the Diagram.PrintManager.Scale and update the PrintGrid size/appearance.

Yep. I missed the Diagram.TemplateApplied event handler.



This is really excellent.



Thank you so much for your help!