Печать WPF FlowDocument - PullRequest
       16

Печать WPF FlowDocument

33 голосов
/ 05 декабря 2008

Я создаю демонстрационное приложение в 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 ]

37 голосов
/ 12 мая 2009

да, сделайте копию 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);
        }

    }
7 голосов
/ 09 декабря 2008

Вы можете использовать код из приведенного ниже 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

2 голосов
/ 22 ноября 2016

Работает как с текстовыми, так и с нетекстовыми визуальными эффектами:

//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");
}
0 голосов
/ 01 мая 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...