Я создаю демонстрационное приложение в 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 перед его печатью? Или есть другой подход, который я должен рассмотреть?





Вы можете использовать код из приведенного ниже URL-адреса, он оборачивает рабочий документ в фиксированный документ и печатает его, большое преимущество заключается в том, что вы можете использовать его для добавления полей, верхних и нижних колонтитулов.
да, сделайте копию 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);
}
}
Это только кажется, чтобы печатать текст, как вы печатаете BlockUIContainer?
@Beaker Ознакомьтесь с этим решением, которое позволяет печатать изображения и другой контейнер BlockUIcontainer: stackoverflow.com/a/18088609/1243372
Я также создаю отчет WPF из документа Flow, но я намеренно использую документ потока в качестве экрана предварительного просмотра печати. Я там, потому что хочу, чтобы поля были такими же. Вы можете прочитать про как я это сделал здесь.
В вашем сценарии я думаю, почему бы просто не сделать копию ваших настроек вместо всего документа потока. Затем вы можете повторно применить настройки, если хотите вернуть документ в исходное состояние.
Я исправил ссылку в этом ответе с помощью WayBackMachine. archive.org/index.php
Следующее работает как с текстовыми, так и с нетекстовыми изображениями:
//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");
}
Ваш вопрос был моим ответом. Спасибо!