Проблемы с XPSDocumentWriter и PrintDialog.PrintDocument

Наша компания разрабатывает приложение (WPF, ориентированное на .NET 3.5) с компонентами построения диаграмм WPF от MindFusion. По всей видимости, печать и сохранение документов XPS приводит к различным ошибкам в разных системах.

Я свел проблему к одному образцу XPS-документа, созданного из нашего приложения. Сначала дадим обзор соответствующих систем и разберем проблемы при сохранении документа xps и печати визуальной диаграммы с использованием нового пути печати WPF в следующем списке:

Примечание. Все три системы имеют Windows XP SP3 с установленным .NET 3.5 Framework SP1.

Использование XpsDocumentWriter для написания документа XPS с помощью Paginator:

ПК 1 - XPS Viewer (работающий с IE 7.0) не работает (даже после переустановки .Net 3.5). XPS Viewer из Essential Pack открывает документ, но вид полностью размыт. Но, как видите, наше приложение справа от снимка экрана использует DocumentViewer для проверки этой проблемы, который работает правильно. Печать из поврежденного средства просмотра XPS дает тот же результат, что и на экране, в то время как печать из встроенной функции печати в DocumentViewer (без вмешательства нашего приложения) дает размытый результат, который немного более читабелен, но все же неприемлем.

ПК 2 - IE XPS Viewer работает правильно. Вывод на печать несоответствующий. Иногда графика (Фигуры) не завершена, или печатающее устройство сообщает о нехватке памяти (с тем же документом).

ПК 3 - IE XPS Viewer работает правильно, но запуск задания на печать всегда приводит к этому исключение в самом IE. Примечание. Все ранее упомянутые проблемы были протестированы с помощью документа XPS (уже упомянутого выше), созданный нашим приложением.

Создание задания на печать с помощью PrintDialog.PrintDocument и Paginator:

Печать из нашего приложения дает единообразный вывод для всей системы: чем больше документ (если говорить о размере страницы), тем более размытым он становится. К сожалению, многие возможные причины уже упущены. код для печати документа довольно прост.

• Вместо использования нашего собственного Paginator я заменил последний другой частью Paginator. компонентов построения диаграмм MindFusion WPF, которые мы используем. Я добился того же результата. (Это утверждение также верно для документов XPSDocuments, сохраненных в виде файла).

• Я использовал последнюю доступную версию драйвера печати.

• Изменения в разрешении PrintTicket, похоже, никоим образом не влияют на вывод.

• Использование другого визуала вместо диаграммы (например, самого окна нашего приложения) не влияет на вывод

Из-за этих различных проблем кажется, что также возможны несколько причин. Предыдущие исключения заставили меня предположить, что некоторые важные настройки отсутствуют в PrintTicket , или что-то ужасно неправильное происходит со сценами преобразования XPS в GDI. Помимо этих предположений, у меня заканчиваются идеи.

Примечание. Все устройства печати имеют драйверы, отличные от XPS. HP Designjet 500, HP 2100

И последнее, но не менее важное: я сериализовал тот же PrintTicket, используемый для файла документа XPS и задание на печать. Буду признателен, если у кого-нибудь возникнут подобные проблемы. Любые предложения приветствуются.


person Alex Maker    schedule 29.07.2009    source источник


Ответы (1)


В настоящее время у меня есть рабочий код, но проблемы с выравниванием все еще возникают. Но печать не размывается. Я даю вам свой код в надежде, что он поможет вам, и мы оба сможем найти решение.

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);
                }
            }
        }
person AZ_    schedule 11.11.2009