Печать WPF FlowDocument

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

Код, который я использую, выглядит следующим образом:

        PrintDialog pd = new PrintDialog();
        fd.PageHeight = pd.PrintableAreaHeight;
        fd.PageWidth = pd.PrintableAreaWidth;
        fd.PagePadding = new Thickness(50);
        fd.ColumnGap = 0;
        fd.ColumnWidth = pd.PrintableAreaWidth;

        IDocumentPaginatorSource dps = fd;
        pd.PrintDocument(dps.DocumentPaginator, "flow doc");

fd - мой FlowDocument, и на данный момент я использую принтер по умолчанию вместо того, чтобы позволять пользователю указывать параметры печати. Он работает нормально, за исключением того, что после печати документа FlowDocument, отображаемый на экране, был изменен на использование параметров, указанных для печати.

Я могу исправить это, вручную сбросив все настройки после печати, но так ли это лучше? Должен ли я сделать копию FlowDocument, прежде чем напечатать ее? Или есть другой подход, который я должен рассмотреть?

4 ответа

Решение

Да, сделайте копию FlowDocument перед печатью. Это потому, что нумерация страниц и поля будут разными. Это работает для меня.

    private void DoThePrint(System.Windows.Documents.FlowDocument document)
    {
        // Clone the source document's content into a new FlowDocument.
        // This is because the pagination for the printer needs to be
        // done differently than the pagination for the displayed page.
        // We print the copy, rather that the original FlowDocument.
        System.IO.MemoryStream s = new System.IO.MemoryStream();
        TextRange source = new TextRange(document.ContentStart, document.ContentEnd);
        source.Save(s, DataFormats.Xaml);
        FlowDocument copy = new FlowDocument();
        TextRange dest = new TextRange(copy.ContentStart, copy.ContentEnd);
        dest.Load(s, DataFormats.Xaml);

        // Create a XpsDocumentWriter object, implicitly opening a Windows common print dialog,
        // and allowing the user to select a printer.

        // get information about the dimensions of the seleted printer+media.
        System.Printing.PrintDocumentImageableArea ia = null;
        System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(ref ia);

        if (docWriter != null && ia != null)
        {
            DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator;

            // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
            paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
            Thickness t = new Thickness(72);  // copy.PagePadding;
            copy.PagePadding = new Thickness(
                             Math.Max(ia.OriginWidth, t.Left),
                               Math.Max(ia.OriginHeight, t.Top),
                               Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), t.Right),
                               Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), t.Bottom));

            copy.ColumnWidth = double.PositiveInfinity;
            //copy.PageWidth = 528; // allow the page to be the natural with of the output device

            // Send content to the printer.
            docWriter.Write(paginator);
        }

    }

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

http://blogs.msdn.com/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin.aspx

Следующее работает как с текстовыми, так и с нетекстовыми визуальными эффектами:

//Clone the source document
var str = XamlWriter.Save(FlowDoc);
var stringReader = new System.IO.StringReader(str);
var xmlReader = XmlReader.Create(stringReader);
var CloneDoc = XamlReader.Load(xmlReader) as FlowDocument;

//Now print using PrintDialog
var pd = new PrintDialog();

if (pd.ShowDialog().Value)
{
  CloneDoc.PageHeight = pd.PrintableAreaHeight;
  CloneDoc.PageWidth = pd.PrintableAreaWidth;
  IDocumentPaginatorSource idocument = CloneDoc as IDocumentPaginatorSource;

  pd.PrintDocument(idocument.DocumentPaginator, "Printing FlowDocument");
}

Я также создаю отчет WPF из документа Flow, но я намеренно использую этот документ в качестве экрана предварительного просмотра. Я хочу, чтобы поля были такими же. О том, как я это сделал, вы можете прочитать здесь.

В вашем сценарии я думаю, почему бы просто не сделать копию ваших настроек, а не весь рабочий документ. Затем вы можете повторно применить настройки, если хотите вернуть документ в исходное состояние.

Другие вопросы по тегам