簡體   English   中英

WPF PrintPreview 獲取 DocumentPaginator 頁面的 PageContent

[英]WPF PrintPreview Get the PageContent of DocumentPaginator Pages

我想使用DocumentViewer為較大的文本編寫自己的 PrintPreview,以便稍后顯示。 我沒有找到任何對我的問題有用的東西。

目前我正在尋找一種方法來獲取各個頁面的內容。 我找到了一種訪問各個頁面的方法,但我無法存儲或獲取它。

使用代碼:

  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文檔獲取到具有許多固定頁面的固定文檔(取決於頁數)?

我討厭它回答我自己的問題。
搜索三天后,我在這里問。
一天后,我找到了一個方法...

很久沒有回答這個問題了。
我嘗試了 Doo Dah 的回答,但問題是它沒有處理流文檔的頁面填充。

因此,我編寫了自己的解決方案(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 並將其傳遞給方法。
添加了 PrintDialog 變量以從我的預覽 window 中調用方法,並且可以傳遞當前的打印機設置。

如果你從你的主程序中調用它,你可以傳遞一個new PrintDialog()null ,沒有區別,因為如果你傳遞null它將創建一個new PrintDialog

對於具有不同類型文本(標題、文本、字體)的 Flowdocument,這對我來說效果很好。

它應該適用於混合的圖片和文本,或者只適用於圖片 - 它使用視覺效果而不是流文檔中的特定內容,因此它也應該適用於分頁符。

我沒有嘗試過 Shahin Dohan 的答案,因為它經常出現同樣的問題。
它是在 MVVM 上編寫的,當其他人編寫它時很難理解。
在我看來,最好在沒有 mvvm 的情況下編寫一個小示例程序,人們可以熟練使用 mvvm 或僅使用代碼。
我了解 mvvm 的機會,但是為了向某人展示如何工作,我只看到了缺點(如果您不展示特定的 mvvm 機制)

WPF中是否可以通過頁碼獲取每個DocumentPage的內容?

您可以按照此操作,然后將每個提取的TextRange添加到您想要的任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM