XPSDocumentWriter和PrintDialog.PrintDocument的问题

时间:2009-07-29 13:16:00

标签: wpf printing printdocument paginator blurry

我们公司正在使用MindFusion的WPF图表组件开发一个应用程序(WPF,针对.NET 3.5)。显然,打印和保存XPS文档会导致不同系统出现各种错误。

我将问题简化为从我们的应用程序创建的单个样本XPS Document。我将首先概述相关系统,并分别保存xps文档并使用以下方法打印图表时解决问题以下列表中的新WPF打印路径:

注意:这三个系统都安装了安装了.NET 3.5 Framework SP1的Windows XP SP3。

使用XpsDocumentWriter使用Paginator编写XPS文档:

PC 1 - XPS Viewer(使用IE 7.0)不起作用(即使在重新安装.Net 3.5之后)。 Essential Pack中的XPS Viewer打开文档,但视图完全模糊。但正如您所看到的,我们在screenshot右侧的应用程序使用DocumentViewer来测试此问题,该问题正常运行。从损坏的XPS Viewer打印产生与屏幕相同的输出,而从DocumentViewer中的集成打印功能打印(无需我们的应用程序干预)会产生模糊输出,这种输出更具可读性,但仍然不可接受。

PC 2 - IE XPS Viewer正常运行。打印输出不一致。有时,图形(形状)不完整,或者打印设备通知内存不足(使用相同的文档)。

PC 3 - IE XPS Viewer正常工作,但启动打印作业始终会导致IE本身内的exception。 注意:所有迄今为止提到的问题都已经过我们的应用程序创建的XPS Document(已在上面提到)测试过。

使用PrintDialog.PrintDocument和Paginator创建打印作业:

从我们的应用程序打印可以为所有系统提供一致的输出:文档越大(以页面媒体大小来衡量),它越模糊。不幸的是,已经省略了许多潜在的原因。 code for printing the document非常简单。

•我没有使用我们自己的Paginator,而是使用我们使用的MindFusion WPF Diagraming Components的另一个Paginator部分替换后者。我取得了同样的结果。 (对于保存为文件的XPSDocuments,此声明也是如此)。

•我使用了最新的打印驱动程序

•对PrintTicket Resolution的更改似乎不会以任何方式影响输出

•使用另一个Visual而不是图表(如我们的应用程序本身的Window)不会影响输出

由于这些不同的问题,似乎也可能有多种原因。之前的排除使我假设PrintTicket中缺少一些关键设置,或者XPS到GDI转换behnd场景发生了严重错误。除了这些假设之外,我的想法已经不多了。

注意:所有打印设备都有非XPS驱动程序。 HP Designjet 500,HP 2100

最后但并非最不重要的是,我序列化了用于XPS Document文件和打印作业的PrintTicket。 如果有人遇到类似的问题,我将感激不尽。欢迎提出任何建议。

1 个答案:

答案 0 :(得分:0)

我目前正在使用代码,但我仍然存在对齐问题。但是打印并没有模糊我给你的代码希望它可以帮助你,我们都可以找到解决方案。

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);
                }
            }
        }