Как просмотреть документ с помощью DocumentViewer с несколькими страницами на листе в WPF - PullRequest
1 голос
/ 07 марта 2020

Как я могу просмотреть документ с DocumentViewer с несколькими страницами на листе (например, 2, 4, 6, 8 и т. Д. c. Страниц на листе) в WPF . По умолчанию DocumentViewer может только просматривать документ с одной страницей на листе . Но я хочу предварительно просмотреть документ с несколькими страницами на листе следующим образом:

Google Chrome Print Dialog Pages Per Sheet Example

Я просто использую элемент управления DocumentViewer в WPF , я хочу просмотреть документ с несколькими страницами на листе , но DocumentViewer не имеет свойства или метода для этого. Поэтому я думаю, что могу изменить свойство DocumentViewer.Document, например изменить документ, поместить несколько страниц на одну страницу и т. Д. c. Но я не знаю, как это сделать.

Заранее спасибо.

1 Ответ

0 голосов
/ 13 марта 2020

Я написал класс, чтобы сложить несколько FixedPage в один FixedPage, он отлично работает.

using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows.Documents;

namespace PreviewHelper
{
    internal enum DocumentOrientation
    {
        Portrait,
        Landscape
    }

    internal class MultiPagesPerSheetHelper
    {
        private readonly int _pagesPerSheet;
        private readonly Size _innerPageSize;
        private readonly FixedDocument _document;
        private readonly DocumentOrientation _documentOrientation;

        private readonly List<int> _allowedPagesPerSheetCount = new List<int> { 1, 2, 4, 6, 9, 16 };
        private readonly List<Size> _allowedPagesPerSheetArrange = new List<Size> { new Size(1, 1), new Size(1, 2), new Size(2, 2), new Size(2, 3), new Size(3, 3), new Size(4, 4) };

        public MultiPagesPerSheetHelper()
        {
            _document = null;
            _pagesPerSheet = 0;
            _innerPageSize = new Size();
            _documentOrientation = DocumentOrientation.Portrait;
        }

        public MultiPagesPerSheetHelper(int pagesPerSheet, FixedDocument document)
        {
            _document = document;
            _pagesPerSheet = pagesPerSheet;
            _innerPageSize = new Size();
            _documentOrientation = DocumentOrientation.Portrait;
        }

        public MultiPagesPerSheetHelper(int pagesPerSheet, FixedDocument document, Size innerPageSize)
        {
            _document = document;
            _pagesPerSheet = pagesPerSheet;
            _innerPageSize = innerPageSize;
            _documentOrientation = DocumentOrientation.Portrait;
        }

        public MultiPagesPerSheetHelper(int pagesPerSheet, FixedDocument document, Size innerPageSize, DocumentOrientation documentOrientation)
        {
            _document = document;
            _pagesPerSheet = pagesPerSheet;
            _innerPageSize = innerPageSize;
            _documentOrientation = documentOrientation;
        }

        public FixedDocument GetMultiPagesPerSheetDocument()
        {
            if (_document == null && _document.Pages.Count == 0 && _pagesPerSheet == 0)
            {
                return new FixedDocument();
            }
            if (_allowedPagesPerSheetCount.Contains(_pagesPerSheet) == false)
            {
                return new FixedDocument();
            }

            FixedDocument doc = new FixedDocument();
            doc.DocumentPaginator.PageSize = _document.DocumentPaginator.PageSize;

            int currentPageCount = 0;
            int pagesPerSheetIndex = _allowedPagesPerSheetCount.IndexOf(_pagesPerSheet);
            int arrangeRows;
            int arrangeColumns;
            if (_documentOrientation == DocumentOrientation.Portrait)
            {
                arrangeRows = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Height;
                arrangeColumns = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Width;
            }
            else
            {
                arrangeRows = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Width;
                arrangeColumns = (int)_allowedPagesPerSheetArrange[pagesPerSheetIndex].Height;
            }
            double innerPageHeight = doc.DocumentPaginator.PageSize.Height / arrangeRows;
            double innerPageWidth = doc.DocumentPaginator.PageSize.Width / arrangeColumns;

            while (currentPageCount < _document.Pages.Count)
            {
                FixedPage outerPage = new FixedPage
                {
                    Width = doc.DocumentPaginator.PageSize.Width,
                    Height = doc.DocumentPaginator.PageSize.Height
                };

                Grid outergrid = new Grid()
                {
                    Width = outerPage.Width,
                    Height = outerPage.Height,
                };

                for (int i = 0; i < arrangeRows; i++)
                {
                    outergrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
                }
                for (int i = 0; i < arrangeColumns; i++)
                {
                    outergrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
                }

                for (int i = 0; i < arrangeRows; i++)
                {
                    for (int j = 0; j < arrangeColumns && currentPageCount < _document.Pages.Count; j++)
                    {
                        Grid innerGrid = new Grid()
                        {
                            Width = innerPageWidth,
                            Height = innerPageHeight,
                            VerticalAlignment = VerticalAlignment.Center,
                            HorizontalAlignment = HorizontalAlignment.Center
                        };
                        innerGrid.SetValue(Grid.RowProperty, i);
                        innerGrid.SetValue(Grid.ColumnProperty, j);

                        string xaml = XamlWriter.Save(_document.Pages[currentPageCount].Child);
                        FixedPage innerPage = XamlReader.Parse(xaml) as FixedPage;

                        if (_innerPageSize.Width == 0 || _innerPageSize.Height == 0 || _innerPageSize.Width == double.NaN || _innerPageSize.Height == double.NaN)
                        {
                            innerPage.Width = outerPage.Width;
                            innerPage.Height = outerPage.Width;
                        }
                        else
                        {
                            innerPage.Width = _innerPageSize.Width;
                            innerPage.Height = _innerPageSize.Height;
                        }

                        innerPage.VerticalAlignment = VerticalAlignment.Center;
                        innerPage.HorizontalAlignment = HorizontalAlignment.Center;

                        double widthRatio;
                        double heightRatio;

                        widthRatio = innerPageWidth / innerPage.Width;
                        heightRatio = innerPageHeight / innerPage.Height;

                        if (innerPage.Height * widthRatio <= innerPageHeight)
                        {
                            innerPage.Width *= widthRatio;
                            innerPage.Height *= widthRatio;

                            innerPage.RenderTransform = new ScaleTransform(widthRatio, widthRatio);
                        }
                        else
                        {
                            innerPage.Width *= heightRatio;
                            innerPage.Height *= heightRatio;

                            innerPage.RenderTransform = new ScaleTransform(heightRatio, heightRatio);
                        }

                        innerGrid.Children.Add(innerPage);
                        outergrid.Children.Add(innerGrid);

                        currentPageCount++;
                    }
                }

                outerPage.Children.Add(outergrid);

                doc.Pages.Add(new PageContent { Child = outerPage });
            }

            return doc;
        }
    }
}

И вы можете использовать его так:

PreviewHelper.MultiPagesPerSheetHelper multiPagesPerSheetHelper = new PreviewHelper.MultiPagesPerSheetHelper(PAGES_PER_SHEET_COUNT, ORGINAL_DOCUMENT, ORGINAL_DOCUMENT_SIZE, DOCUMENT_ORIENTATION);
FixedDocument newDocument = multiPagesPerSheetHelper.GetMultiPagesPerSheetDocument();

Это будет работать так:

Print Dialog Pages Per Sheet

...