我如何能产生与QUOT;打印preVIEW"在一个WPF应用程序的FlowDocument?应用程序、生与、QUOT、preVIEW

2023-09-02 21:21:13 作者:荒词旧笺

我的各种WPF应用程序显示的FlowDocument的。我可以打印出来,用的的答案中描述的方法的打印WPF的FlowDocument 。

Various WPF applications of mine display FlowDocument's. I'm able to print them, using the approach described in the answer to Printing a WPF FlowDocument.

现在我想添加一个打印preVIEW的能力。在正常情况下,我在打印时显示在窗口中的FlowDocument,因此我不需要打印preVIEW即可。但在某些情况下的FlowDocument到打印构造上的即时在内存中。而在这种情况下,我想在打印前显示它。

Now I'd like to add a "print preview" capability. In the normal case, I am printing the FlowDocument that is displayed in the Window, and so I wouldn't need a Print Preview then. But in some cases the FlowDocument to print is constructed on-the-fly in memory. And in these cases I'd like to display it before printing.

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

Now, I can certainly pop a new window and display the FlowDocument, but

我要的preVIEW真正的感觉的喜欢它的打印操作的一部分,而不仅仅是在应用程序中的另一个窗口。

I want the preview to really feel like it is part of the printing operation, and not just another Window in the app.

我不希望在FlowDocumentScrollViewer正常的FlowDocument。而不是任何尺寸它需要被限制于纸张,特定HXW比率,和分页的大小。

I don't want a normal FlowDocument in a FlowDocumentScrollViewer. Rather than being "any size" it needs to be constrained to the size of the paper, a specific HxW ratio, and paginated.

建议?

我应该只使用一个标准的窗口,在此情况下,如何保证我的FlowDocument的是在合适的比例?

should I just use a standard Window, and in that case, how to I ensure the FlowDocument is at the proper ratio?

有没有更整合的方式做PrintDialog类UI的范围是Windows的一部分内的preVIEW?

is there a more "integrated" way to do the preview within the scope of the PrintDialog UI that is part of Windows?

感谢

推荐答案

以提示从注释加入到我的问题,我这样做:

Taking the hint from the comment added to my question, I did this:

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
            {
            }
        }
    }
} 

它的作用:它实际上打印的可视内容为XPS文档。然后,它加载印刷XPS文档并且在存储为串,而不是作为单独的模块,并在运行时动态地加载一个非常简单的XAML文件显示。出现的窗口中具有的DocumentViewer按钮:打印,调节到最大页面宽度,依此类推。

What it does: it actually prints the content of a visual into an XPS document. Then it loads the "printed" XPS document and displays it in a very simple XAML file that is stored as a string, rather than as a separate module, and loaded dynamically at runtime. The resulting Window has the DocumentViewer buttons: print, adjust-to-max-page-width, and so on.

我还添加了一些code隐藏搜索框。请参阅this回答的 WPF:?我如何删除搜索框中的DocumentViewer 的了解我是怎么做的。

I also added some code to hide the Search box. See this answer to WPF: How can I remove the searchbox in a DocumentViewer? for how I did that.

的效果是这样的:

的XpsDocument可以在ReachFramework DLL中发现和XpsDocumentWriter可以在System.Printing DLL这两者必须被加入作为参考的项目中找到

The XpsDocument can be found in the ReachFramework dll and the XpsDocumentWriter can be found in the System.Printing dll both of which must be added as references to the project