如何在WPF应用程序中生成FlowDocument的"打印预览"?

Che*_*eso 15 .net printing wpf flowdocument flowdocumentscrollviewer

我的各种WPF应用程序显示FlowDocument的.我可以使用打印WPF FlowDocument 的答案中描述的方法打印它们.

现在我想添加一个"打印预览"功能.在正常情况下,我正在打印窗口中显示的FlowDocument,因此我不需要打印预览.但在某些情况下,要打印的FlowDocument是在内存中即时构建的.在这些情况下,我想在打印前显示它.

现在,我当然可以弹出一个新窗口并显示FlowDocument,但是

  1. 我希望预览真的感觉它是打印操作的一部分,而不仅仅是应用程序中的另一个窗口.

  2. 我不想在FlowDocumentScrollViewer中使用普通的FlowDocument.它不是"任何大小",而是需要约束纸张的大小,特定的HxW比率和分页.

建议?

  • 我应该只使用标准窗口,在这种情况下,如何确保FlowDocument处于适当的比例?

  • 是否有更"集成"的方式在Windows的PrintDialog UI范围内进行预览?

谢谢

Che*_*eso 22

从评论的提示中添加了我的问题,我这样做了:

private string _previewWindowXaml =
    @"<Window
        xmlns                 ='http://schemas.microsoft.com/netfx/2007/xaml/presentation'
        xmlns:x               ='http://schemas.microsoft.com/winfx/2006/xaml'
        Title                 ='Print Preview - @@TITLE'
        Height                ='200'
        Width                 ='300'
        WindowStartupLocation ='CenterOwner'>
        <DocumentViewer Name='dv1'/>
     </Window>";

internal void DoPreview(string title)
{
    string fileName = System.IO.Path.GetRandomFileName();
    FlowDocumentScrollViewer visual = (FlowDocumentScrollViewer)(_parent.FindName("fdsv1"));
    try
    {
        // write the XPS document
        using (XpsDocument doc = new XpsDocument(fileName, FileAccess.ReadWrite))
        {
            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
            writer.Write(visual);
        }

        // Read the XPS document into a dynamically generated
        // preview Window 
        using (XpsDocument doc = new XpsDocument(fileName, FileAccess.Read))
        {
            FixedDocumentSequence fds = doc.GetFixedDocumentSequence();

            string s = _previewWindowXaml;
            s = s.Replace("@@TITLE", title.Replace("'", "&apos;"));

            using (var reader = new System.Xml.XmlTextReader(new StringReader(s)))
            {
                Window preview = System.Windows.Markup.XamlReader.Load(reader) as Window;

                DocumentViewer dv1 = LogicalTreeHelper.FindLogicalNode(preview, "dv1") as DocumentViewer;
                dv1.Document = fds as IDocumentPaginatorSource;


                preview.ShowDialog();
            }
        }
    }
    finally
    {
        if (File.Exists(fileName))
        {
            try
            {
                File.Delete(fileName);
            }
            catch
            {
            }
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

它的作用:它实际上将视觉内容打印到XPS文档中.然后它加载"打印的"XPS文档并将其显示在一个非常简单的XAML文件中,该文件存储为字符串,而不是作为单独的模块,并在运行时动态加载.生成的窗口具有DocumentViewer按钮:print,adjust-to-max-page-width等.

我还添加了一些代码来隐藏搜索框.请参阅WPF的这个答案:如何在DocumentViewer中删除搜索框?我是怎么做到的

效果是这样的:

替代文字http://i48.tinypic.com/2hzkfat.jpg

可以在ReachFramework dll中找到XpsDocument,并且可以在System.Printing dll中找到XpsDocumentWriter,这两者都必须作为对项目的引用添加

  • 什么是_parent? (6认同)
  • 我无法使用您的代码,因为我的项目找不到XpsDocument并且无法解决它.我必须在项目中添加哪些参考? (2认同)
  • 嗯,很高兴它为您提供了预览,但它并不是一个打印对话框。窗口中没有太多打印选项。 (2认同)