Как печатать на нескольких страницах в UWP - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть система печати, которая работает в моем проекте UWP.

Для подготовки содержимого для печати я использую это:

(Источник: https://blogs.u2u.be/diederik/post/Printing-from-MVVM-XAML-Windows-8-Store-apps)

public void RegisterForPrinting(Page sourcePage, Type printPageType, object viewModel)
        {
            this.callingPage = sourcePage;

            if (PrintingRoot == null)
            {
                this.OnStatusChanged(new PrintServiceEventArgs("The calling page has no PrintingRoot Canvas."));
                return;
            }

            this.printPageType = printPageType;
            this.DataContext = viewModel;

            // Prep the content
            this.PreparePrintContent();

            // Create the PrintDocument.
            printDocument = new PrintDocument();

            // Save the DocumentSource.
            printDocumentSource = printDocument.DocumentSource;

            // Add an event handler which creates preview pages.
            printDocument.Paginate += PrintDocument_Paginate;

            // Add an event handler which provides a specified preview page.
            printDocument.GetPreviewPage += PrintDocument_GetPrintPreviewPage;

            // Add an event handler which provides all final print pages.
            printDocument.AddPages += PrintDocument_AddPages;

            // Create a PrintManager and add a handler for printing initialization.
            PrintManager printMan = PrintManager.GetForCurrentView();

            try
            {
                printMan.PrintTaskRequested += PrintManager_PrintTaskRequested;
                this.OnStatusChanged(new PrintServiceEventArgs("Registered successfully."));
            }
            catch (InvalidOperationException)
            {
                // Probably already registered.
                this.OnStatusChanged(new PrintServiceEventArgs("You were already registered."));
            }
        }
private void PreparePrintContent()
        {
            // Create and populate print page.
            var printPage = Activator.CreateInstance(this.printPageType) as Page;

            printPage.DataContext = this.DataContext;

            // Create print template page and fill invisible textblock with empty paragraph.
            // This pushes all real content into the overflow.
            firstPage = new PrintPage();
            firstPage.AddContent(new Paragraph());

            // Move content from print page to print template - paragraph by paragraph.
            var printPageRtb = printPage.Content as RichTextBlock;
            while (printPageRtb.Blocks.Count > 0)
            {
                var paragraph = printPageRtb.Blocks.First() as Paragraph;
                printPageRtb.Blocks.Remove(paragraph);

                var container = paragraph.Inlines[0] as InlineUIContainer;
                if (container != null)
                {
                    // Place the paragraph in a new textblock, and measure it.
                    var measureRtb = new RichTextBlock();
                    measureRtb.Blocks.Add(paragraph);
                    PrintingRoot.Children.Clear();
                    PrintingRoot.Children.Add(measureRtb);
                    PrintingRoot.InvalidateMeasure();
                    PrintingRoot.UpdateLayout();
                    measureRtb.Blocks.Remove(paragraph);

                    // Apply line height to trigger overflow.
                    paragraph.LineHeight = measureRtb.ActualHeight;
                }
                firstPage.AddContent(paragraph);
            };

            // Send it to the printing root.
            PrintingRoot.Children.Clear();
            PrintingRoot.Children.Add(firstPage);
        }

PrintPage

public sealed partial class PrintPage : Page
    {
        public PrintPage()
        {
            this.InitializeComponent();
        }

        public PrintPage(RichTextBlockOverflow textLinkContainer)
            : this()
        {
            textLinkContainer.OverflowContentTarget = continuationPageLinkedContainer;
        }

        internal void AddContent(Paragraph block)
        {
            this.textContent.Blocks.Add(block);
        }
    }
<RichTextBlock x:Name="textContent"
                           Grid.Row="1"
                           Grid.ColumnSpan="2"
                           FontSize="18"
                           OverflowContentTarget="{Binding ElementName=continuationPageLinkedContainer}"
                           IsTextSelectionEnabled="True"
                           TextAlignment="Left"
                           FontFamily="Segoe UI"
                           VerticalAlignment="Top"
                           HorizontalAlignment="Left">
</RichTextBlock>

<RichTextBlockOverflow x:Name="continuationPageLinkedContainer" Grid.Row="2" />

sourcePage

<RichTextBlock x:Name="PrintContent">
        <!-- Content -->
    </RichTextBlock>

При настройке программы мне нужно иметь возможность печатать каждый абзац RichTextBox на отдельных страницах.

Возможно ли это?

1 Ответ

1 голос
/ 13 февраля 2020

Мне нужно иметь возможность печатать каждый абзац RichTextBox на отдельных страницах.

Если вы хотите напечатать каждый абзац RichTextBox на отдельной странице вам нужно создать несколько PrintPages для каждого абзаца, затем поместить PrintPage в Printing Root и список PrintPages. После этого, когда вы добавляете страницы предварительного просмотра, вам нужно выполнить итерацию PrintPages и добавить их.

Я внес следующие изменения, и вот полный пример , вы можете загрузить и проверить его.

private void PreparePrintContent()
{
    PrintingRoot.Children.Clear();
    // Create and populate print page.
    var printPage = Activator.CreateInstance(this.printPageType) as Page;

    printPage.DataContext = this.DataContext;

    var printPageRtb = printPage.Content as RichTextBlock;
    while (printPageRtb.Blocks.Count > 0)
    {
        PrintPage firstPage = new PrintPage();
        firstPage.AddContent(new Paragraph());
        var paragraph = printPageRtb.Blocks.First() as Paragraph;
        printPageRtb.Blocks.Remove(paragraph);

        firstPage.AddContent(paragraph);
        NeedToPrintPages.Add(firstPage);
        PrintingRoot.Children.Add(firstPage);
    };
}

private RichTextBlockOverflow AddOnePrintPreviewPage(RichTextBlockOverflow lastRTBOAdded, PrintPageDescription printPageDescription,int index)
{
    ......
    if (lastRTBOAdded == null)
    {
        // If this is the first page add the specific scenario content
        page = NeedToPrintPages[index];
    }
    ......
}

private void PrintDocument_Paginate(object sender, PaginateEventArgs e)
{
    // Clear the cache of preview pages 
    printPreviewPages.Clear();
    this.pageNumber = 0;

    // Clear the printing root of preview pages
    PrintingRoot.Children.Clear();
    for (int i = 0; i < NeedToPrintPages.Count; i++) {
        // This variable keeps track of the last RichTextBlockOverflow element that was added to a page which will be printed
        RichTextBlockOverflow lastRTBOOnPage;
        // Get the PrintTaskOptions
        PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);

        // Get the page description to deterimine how big the page is
        PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);

        // We know there is at least one page to be printed. passing null as the first parameter to
        // AddOnePrintPreviewPage tells the function to add the first page.
        lastRTBOOnPage = AddOnePrintPreviewPage(null, pageDescription,i);

        // We know there are more pages to be added as long as the last RichTextBoxOverflow added to a print preview
        // page has extra content
        while (lastRTBOOnPage.HasOverflowContent && lastRTBOOnPage.Visibility == Windows.UI.Xaml.Visibility.Visible)
        {
            lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription,i);
        }

    }

    PrintDocument printDoc = (PrintDocument)sender;

    // Report the number of preview pages created
    printDoc.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Intermediate);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...