C# 如何使用DocumentViewer预览文档,在WPF中每页多页

C# 如何使用DocumentViewer预览文档,在WPF中每页多页,c#,wpf,documentviewer,C#,Wpf,Documentviewer,如何使用WPF中的DocumentViewer和每页多页(如每页2、4、6、8页等)预览文档。默认情况下,DocumentViewer只能预览每页一页的文档。但我想预览每页多页的文档,如下所示: PreviewHelper.MultiPagesPerSheetHelper multiPagesPerSheetHelper = new PreviewHelper.MultiPagesPerSheetHelper(PAGES_PER_SHEET_COUNT, ORGINAL_DOCUMENT, OR

如何使用WPF中的
DocumentViewer
每页多页(如每页2、4、6、8页等)预览文档。默认情况下,
DocumentViewer
只能预览每页一页的文档。但我想预览每页多页的文档,如下所示:

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

我只是在WPF中使用了
DocumentViewer
控件,我想查看每页多页的文档,但是
DocumentViewer
没有这样做的属性或方法。所以我想我可以更改
DocumentViewer.Document
属性,比如更改文档、将多页放入一页等,但我不知道如何做到这一点


提前感谢。

我写了一个类,将几个
固定页面
放在一个
固定页面
中,它工作得非常好

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();

请显示代码示例,并告诉我您试图解决什么问题?@aepot,我只是使用WPF中的
DocumentViewer
控件,我想查看每页有多页的文档,但
DocumentViewer
没有属性或方法来实现这一点。所以我想我可以更改
DocumentViewer.Document
属性,比如更改文档,将多页放入一页,等等。但是我不知道怎么做。你试过了吗?@aepot,
MaxPagesAcross
属性会让你一次查看多页,但我想做的是在预览和打印时在一张纸上显示多个页面。您可以在Google Chrome打印对话框中找到“每页打印”选项,这就是我要做的。当您调用
Print()
时,您希望将每页打印传递到“打印预览”对话框,对吗?所以,我在MSDN页面上找不到任何方法。