views:

818

answers:

2

Our company is developing an application (WPF, targeted to .NET 3.5) with the WPF Diagramming Components from MindFusion.Apparently, printing and saving XPS Documents results in various errors on different systems.

I reduced the problem to a single sample XPS Document created from our application.I'll first give an overview of the concerned systems and break down the issues when respectively saving an xps document and printing the diagram visual using the new WPF Printing Path in the following list:

Note: All three systems have Windows XP SP3 with .NET 3.5 Framework SP1 installed.

Using the XpsDocumentWriter to write a XPS document with the Paginator:

PC 1 - The XPS Viewer (working with IE 7.0) doesn’t work (even after reinstall of .Net 3.5). XPS Viewer from the Essential Pack opens the document, but the view is completely blurred. But as you can see, our application on the right side of the screenshot uses a DocumentViewer to test this issue, which works correctly. Printing from the corrupted XPS Viewer results in the same output as on screen, while printing from the integrated print function in the DocumentViewer ( without intervention from our application) gives a blurry output which is a little more readable, but still not acceptable.

PC 2 - The IE XPS Viewer works correctly. The print ouput is inconsistent. Sometimes, the graphics (Shapes) are not complete, or the printing device notifies about lack of memory (with the same document).

PC 3 – The IE XPS Viewer works correctly, but initiating a print job always leads to this exception within IE itself. Note: All heretofore mentioned issues have been tested with the XPS Document (already mentioned above) created by our application.

Creating a print job with PrintDialog.PrintDocument and the Paginator:

Printing from our application gives a consistent output with all system: the bigger the document (speaking in term of the page media size), the more blurry it gets. Unfortunately, a lot of potential causes have been already omitted. The code for printing the document is fairly simple.

• Instead of using our own Paginator, I replaced the latter with another Paginator part of the MindFusion WPF Diagraming Components we use. I achieved the same result. (This statement is also true for XPSDocuments saved as file).

• I used the latest print driver available

• Changes to PrintTicket Resolution doesn’t seem to affect the ouput in any way

• Using another Visual instead of a diagram (like the Window of our Application itself) doesn’t affect the output

Due to these various issues, it seems that multiple causes are also probable. The previous exclusions lead me to assume that some crucial settings are missing in the PrintTicket, or something terribly wrong happens with the XPS to GDI Conversion behnd scenes. Apart from these assumptions, I'm running out of ideas.

Note: All print devices have non-XPS Drivers. HP Designjet 500, HP 2100

Last but not least, I serialised the same PrintTicket used for XPS Document file and the print job. I would be thankful if anybody has experienced similar issues. Any suggestion is welcome.

A: 

I have currently working code but I am still having alignment issues. But print is not blurred I am giving you my code in hope that it may help you and we both could find a solution.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Documents; using System.Windows; using System.Windows.Media; using System.Diagnostics; `using System.Globalization; using System.Windows.Controls; using System.Data;

namespace VD { public class CustomPaginator : DocumentPaginator { private int _RowsPerPage; private Size _PageSize; private int _Rows; public static DataTable dtToPrint; public CustomPaginator() {
} public CustomPaginator(int rows, Size pageSize, DataTable dt) { _Rows = rows; PageSize = pageSize; dtToPrint = dt; }

public override DocumentPage GetPage(int pageNumber)
{
  int currentRow = _RowsPerPage * pageNumber;

  var page = new PageElement(currentRow, Math.Min(_RowsPerPage, _Rows - currentRow))
  {
    Width = PageSize.Width,
    Height = PageSize.Height,
  };

  page.Measure(PageSize);
  page.Arrange(new Rect(new Point(0,0), PageSize));     

  return new DocumentPage(page);
}

public override bool IsPageCountValid
{ get { return true; } }

public override int PageCount
{ get { return (int)Math.Ceiling(_Rows / (double)_RowsPerPage); } }

public DataTable getDtProtols
{
    get
    {
        return dtToPrint;
    }
}
public override Size PageSize
{
  get { return _PageSize; }
  set
  {
    _PageSize = value;

    _RowsPerPage = PageElement.RowsPerPage(PageSize.Height);

    //Can't print anything if you can't fit a row on a page
    Debug.Assert(_RowsPerPage > 0);
  }
}

public override IDocumentPaginatorSource Source
{ get { return null; } }

}

public class PageElement : UserControl { private const int PageMargin = 75; private const int HeaderHeight = 25; private const int LineHeight = 20; private const int ColumnWidth = 140;

private CustomPaginator objParent = new CustomPaginator();
private DataTable ProtocolsDT = null;
private int _CurrentRow;
private int _Rows;

public PageElement(int currentRow, int rows)
{
  Margin = new Thickness(PageMargin);
  _CurrentRow = currentRow;
  _Rows = rows;
}

private static FormattedText MakeText(string text)
{
  return new FormattedText(text, CultureInfo.CurrentCulture,
    FlowDirection.LeftToRight,
    new Typeface("Tahoma"), 14, Brushes.Black);
}

public static int RowsPerPage(double height)
{
  return (int)Math.Floor((height - (2 * PageMargin)
    - HeaderHeight) / LineHeight);
}

protected override void OnRender(DrawingContext dc)
{
    ProtocolsDT = objParent.getDtProtols;
  Point curPoint = new Point(0, 0);

  dc.DrawText(MakeText("Host Names"),curPoint );
  curPoint.X += ColumnWidth;
  for (int i = 1; i < ProtocolsDT.Columns.Count; i++)
  {
      dc.DrawText(MakeText(ProtocolsDT.Columns[i].ToString()), curPoint);
    curPoint.X += ColumnWidth;
  }

  curPoint.X = 0;
  curPoint.Y += LineHeight;

  dc.DrawRectangle(Brushes.Black, null, new Rect(curPoint, new Size(Width, 2)));
  curPoint.Y += HeaderHeight - LineHeight;

  Random numberGen = new Random();
  //for (int i = _CurrentRow; i < _CurrentRow + _Rows; i++)
  //{
    //  dc.DrawText(MakeText(ProtocolsDT.Rows[i][0].ToString()), curPoint);
    //curPoint.X += ColumnWidth;
    for (int j = 0; j < ProtocolsDT.Rows.Count; j++)
    {
        for (int z = 0; z < ProtocolsDT.Rows[j].ItemArray.Length; z++)
        {
            dc.DrawText(MakeText(ProtocolsDT.Rows[j].ItemArray[z].ToString()), curPoint);
            curPoint.X += ColumnWidth;
        }
        curPoint.Y += LineHeight;
        curPoint.X = 0;
      //dc.DrawText(MakeText(ProtocolsDT.Rows[j].ItemArray[1].ToString()), curPoint);
      //curPoint.X += ColumnWidth;
      //dc.DrawText(MakeText(ProtocolsDT.Rows[j].ItemArray[2].ToString()), curPoint);
      //curPoint.X += ColumnWidth;
    //}
    //curPoint.Y += LineHeight;
    //curPoint.X = 0;
  }
}

} }

Another Class

private void PrintDataTable(DataTable dt)
    {
        var printDialog = new PrintDialog();
        if (printDialog.ShowDialog() == true)
        {                
            var paginator = new CustomPaginator(dt.Rows.Count,
              new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight),dt);
            try
            {
                printDialog.PrintDocument(paginator, "Running Protocols Report");
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, "Unable to print protocol information. Please check your printer settings.", "VD", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
            }
        }
    }
Aizaz
A: 

Hi Aizaz, I tried ur code to print my WPF DataGrid which exceeds datagrid size. Data did print but printing 1) previously selected datagrid data and 2) also 2nd, 3rd pages repeats the same as 1st page. Kindly help me in this issue, thanks in advance. -Sheik.

imsheikak.tech