I am writing a note-taking application in WPF, using a FlowDocument
for each individual note. The app searches and filters notes by tags. I want to print all notes in the current filtered list as separate documents, and I only want to show a single Print Dialog at the beginning of the job.
我正在WPF中写一个笔记记录应用程序,为每个单独的笔记使用FlowDocument。该应用按标签搜索和过滤笔记。我想将当前筛选列表中的所有笔记打印为单独的文档,我只想在作业开头显示一个打印对话框。
I found a good print example in this thread, but it is geared toward printing a single FlowDocument
, so it uses a CreateXpsDocumentWriter()
overload that displays a Print Dialog.
我在这个帖子中找到了一个很好的打印示例,但是它适用于打印单个FlowDocument,因此它使用CreateXpsDocumentWriter()重载来显示打印对话框。
So, here's my question: Can anyone suggest some good code for printing a FlowDocument
without displaying a PrintDialog
? I figure I'll display the Print Dialog at the beginning of the procedure and then loop through my notes collection to print each FlowDocument
.
所以,这是我的问题:有人可以建议一些好的代码来打印FlowDocument而不显示PrintDialog吗?我想我将在程序开始时显示Print Dialog,然后循环我的notes集合以打印每个FlowDocument。
2 个解决方案
#1
3
I have rewritten my answer to this question, because I did find a better way to print a set of FlowDocuments, while showing the Print Dialog only once. The answer comes from MacDonald, Pro WPF in C# 2008 (Apress 2008) in Chapter 20 at p. 704.
我已经重写了我对这个问题的回答,因为我确实找到了一种更好的方法来打印一组FlowDocuments,同时只显示一次Print Dialog。答案来自MacDonald,Pro WPF in C#2008(Apress 2008),第20章,p。 704。
My code bundles a set of Note objects into an IList called notesToPrint and gets the FlowDocument for each Note from a DocumentServices class in my app. It sets the FlowDocument boundaries to match the printer and sets a 1-inch margin. Then it prints the FlowDocument, using the document's DocumentPaginator property. Here's the code:
我的代码将一组Note对象捆绑到名为notesToPrint的IList中,并从我的应用程序中的DocumentServices类获取每个Note的FlowDocument。它设置FlowDocument边界以匹配打印机并设置1英寸的边距。然后使用文档的DocumentPaginator属性打印FlowDocument。这是代码:
// Show Print Dialog
var printDialog = new PrintDialog();
var userCanceled = (printDialog.ShowDialog() == false);
if(userCanceled) return;
// Print Notes
foreach(var note in notesToPrint)
{
// Get next FlowDocument
var collectionFolderPath = DataStore.CollectionFolderPath;
var noteDocument = DocumentServices.GetFlowDocument(note, collectionFolderPath) ;
// Set the FlowDocument boundaries to match the page
noteDocument.PageHeight = printDialog.PrintableAreaHeight;
noteDocument.PageWidth = printDialog.PrintableAreaWidth;
// Set margin to 1 inch
noteDocument.PagePadding = new Thickness(96);
// Get the FlowDocument's DocumentPaginator
var paginatorSource = (IDocumentPaginatorSource)noteDocument;
var paginator = paginatorSource.DocumentPaginator;
// Print the Document
printDialog.PrintDocument(paginator, "FS NoteMaster Document");
}
This is a pretty simple approach, with one significant limitation: It doesn't print asynchronously. To do that, you would have to perform this operation on a background thread, which is how I do it.
这是一个非常简单的方法,有一个显着的限制:它不会异步打印。要做到这一点,你必须在后台线程上执行此操作,这就是我的工作方式。
#2
1
Just a loop after you have got the printDialog
.
获得printDialog后只需一个循环。
for(int i=0 i<document.count i++)
printdocument((document[i] as iDocumentPaginator),"title"+[i]);
#1
3
I have rewritten my answer to this question, because I did find a better way to print a set of FlowDocuments, while showing the Print Dialog only once. The answer comes from MacDonald, Pro WPF in C# 2008 (Apress 2008) in Chapter 20 at p. 704.
我已经重写了我对这个问题的回答,因为我确实找到了一种更好的方法来打印一组FlowDocuments,同时只显示一次Print Dialog。答案来自MacDonald,Pro WPF in C#2008(Apress 2008),第20章,p。 704。
My code bundles a set of Note objects into an IList called notesToPrint and gets the FlowDocument for each Note from a DocumentServices class in my app. It sets the FlowDocument boundaries to match the printer and sets a 1-inch margin. Then it prints the FlowDocument, using the document's DocumentPaginator property. Here's the code:
我的代码将一组Note对象捆绑到名为notesToPrint的IList中,并从我的应用程序中的DocumentServices类获取每个Note的FlowDocument。它设置FlowDocument边界以匹配打印机并设置1英寸的边距。然后使用文档的DocumentPaginator属性打印FlowDocument。这是代码:
// Show Print Dialog
var printDialog = new PrintDialog();
var userCanceled = (printDialog.ShowDialog() == false);
if(userCanceled) return;
// Print Notes
foreach(var note in notesToPrint)
{
// Get next FlowDocument
var collectionFolderPath = DataStore.CollectionFolderPath;
var noteDocument = DocumentServices.GetFlowDocument(note, collectionFolderPath) ;
// Set the FlowDocument boundaries to match the page
noteDocument.PageHeight = printDialog.PrintableAreaHeight;
noteDocument.PageWidth = printDialog.PrintableAreaWidth;
// Set margin to 1 inch
noteDocument.PagePadding = new Thickness(96);
// Get the FlowDocument's DocumentPaginator
var paginatorSource = (IDocumentPaginatorSource)noteDocument;
var paginator = paginatorSource.DocumentPaginator;
// Print the Document
printDialog.PrintDocument(paginator, "FS NoteMaster Document");
}
This is a pretty simple approach, with one significant limitation: It doesn't print asynchronously. To do that, you would have to perform this operation on a background thread, which is how I do it.
这是一个非常简单的方法,有一个显着的限制:它不会异步打印。要做到这一点,你必须在后台线程上执行此操作,这就是我的工作方式。
#2
1
Just a loop after you have got the printDialog
.
获得printDialog后只需一个循环。
for(int i=0 i<document.count i++)
printdocument((document[i] as iDocumentPaginator),"title"+[i]);