WPF打印预览获取文档分页程序页面的页面内容

h5qlskok  于 2022-12-19  发布在  其他
关注(0)|答案(2)|浏览(225)

我想为较大的文本编写自己的打印预览,使用DocumentViewer稍后显示它。我没有找到任何有用的东西来解决我的问题。
目前我正在寻找一种方法来获取单个页面的内容。我找到了一种方法来访问单个页面,但我不能存储或获取它。
使用代码:

DocumentPaginator dpPages = (DocumentPaginator)((IDocumentPaginatorSource)twhtTemp.BuildTemplateControl(txtHeader, txtContent, pdlgPrint)).DocumentPaginator;
            dpPages.ComputePageCount();

            var fixedDocument = new FixedDocument();

            for (int iPages= 0; iPages < dpPages.PageCount; iPages++)
            {
                
                var pageContent = new PageContent();
                var fixedPage = new FixedPage();

                fixedPage.Width = pdlgPrint.PrintableAreaWidth;
                fixedPage.Height = pdlgPrint.PrintableAreaHeight;
                pageContent.Child = fixedPage;
                fixedDocument.Pages.Add(pageContent);
            }

我已经为每个现有页面添加了一个新页面,但无法获取该页面的内容。
到目前为止我知道,我需要一个UIElement添加到fixedPage.Children
或者有没有更简单的方法把一个flowdocument转换成一个有很多固定页面的固定文档(取决于页数)?

7z5jn7bk

7z5jn7bk1#

我讨厌回答自己的问题。
在找了三天之后,我问了这里。
一天后我找到了一个方法...
这个问题已经很久没有答案了。
我尝试了Doo Dah的解决方案,但问题是它没有处理流程文档的页面填充。
因此,我写下了自己的解决方案(斗达的回答帮助我完成了它):

public FixedDocument Get_Fixed_From_FlowDoc(FlowDocument flowDoc, PrintDialog printDlg)
{
           var fixedDocument = new FixedDocument();
            try
            {
                if (printDlg != null)
                {
                    pdlgPrint = printDlg;
                }

            if (pdlgPrint == null)
            {
                pdlgPrint = new PrintDialog();
            }

            DocumentPaginator dpPages = (DocumentPaginator)((IDocumentPaginatorSource)flowDoc).DocumentPaginator;
            dpPages.ComputePageCount();
            PrintCapabilities capabilities = pdlgPrint.PrintQueue.GetPrintCapabilities(pdlgPrint.PrintTicket);
           

            for (int iPages= 0; iPages < dpPages.PageCount; iPages++)
            {

                var page = dpPages.GetPage(iPages);
                var pageContent = new PageContent();
                var fixedPage = new FixedPage();

                Canvas canvas = new Canvas();

                VisualBrush vb = new VisualBrush(page.Visual);
                vb.Stretch = Stretch.None;
                vb.AlignmentX = AlignmentX.Left;
                vb.AlignmentY = AlignmentY.Top;
                vb.ViewboxUnits = BrushMappingMode.Absolute;
                vb.TileMode = TileMode.None;
                vb.Viewbox = new Rect(0, 0, capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);

                FixedPage.SetLeft(canvas, 0);
                FixedPage.SetTop(canvas, 0);
                canvas.Width = capabilities.PageImageableArea.ExtentWidth;
                canvas.Height = capabilities.PageImageableArea.ExtentHeight;
                canvas.Background = vb;

                fixedPage.Children.Add(canvas);

                fixedPage.Width = pdlgPrint.PrintableAreaWidth;
                fixedPage.Height = pdlgPrint.PrintableAreaHeight;
                pageContent.Child = fixedPage;
                fixedDocument.Pages.Add(pageContent);
            }
            dv1.ShowPageBorders = true;

        }
        catch (Exception)
        {
            throw;
        }
        return fixedDocument;
    }

您必须为之前显示的内容构建一个FlowDocument,并将其传递给Method。
添加了PrintDialog变量以从预览窗口调用方法,并可以传递当前打印机设置。
如果从主程序调用它,可以传递new PrintDialog()null,没有区别,因为如果传递null,它将创建new PrintDialog
这对我来说在一个有不同类型文本(标题,文本,字体)的Flowdocument中工作得很好。
它应该与图片和文本混合使用,或者也可以只使用图片--它使用的是视觉效果,而不是流程文档中的特定内容,因此它也应该与分页符一起使用。
我没有尝试沙欣·杜汉的答案,因为这是一个经常出现的问题。
它是在MVVM写的,当另一个人写的时候很难理解。
在我看来,写一个没有mvvm的示例程序会更好,人们可以把它改编成mvvm,或者只使用代码。
我理解mvvm的机会,但要向某人展示如何工作的东西,我只看到缺点(如果你不会展示一个特定的mvvm技工)

ozxc1zmp

ozxc1zmp2#

Is it possible in WPF to get content of each DocumentPage by page number?
您可以按照此操作,然后将每个提取的TextRange添加到您想要的任何内容。

相关问题