C# WPF DocumentViewer, DocumentPaginator, print zoom issues.

Afon.zhang 396 Reputation points
2021-12-28T05:49:39.18+00:00

When I use DocumentPaginator, I want to print on different printing papers (such as A4, A5, etc.). I have a doc object in xaml as follows:
DocumentPaginator doc = ((content.Content as DocumentViewer).Document).DocumentPaginator;
FittedDocumentPaginator fdp = new FittedDocumentPaginator(doc,0.3 );

    public class FittedDocumentPaginator: DocumentPaginator
    {
        public DocumentPaginator ParentDocument {get; private set;}
        public double Scale {get; private set;}
        private readonly ScaleTransform _sTransform;

        public FittedDocumentPaginator(DocumentPaginator baseDp, double scale)
        {
            if (baseDp == null)
                return;

            ParentDocument = baseDp;
            Scale = scale;
            _sTransform = new ScaleTransform(scale, scale); //Zoom
        }

        private DocumentPage CreatePage(Grid grid)
        {
            var box = this.SizingPageGrid(grid);

            return new DocumentPage(grid, this.PageSize, box, box);
        }

        private Rect SizingPageGrid(Grid grid)
        {
            var box = new Rect(new Point(0, 0), this.PageSize);

            grid.InvalidateArrange();
            grid.UpdateLayout();
            grid.Measure(this.PageSize);
            grid.Arrange(box);

            return box;
        }

        public override DocumentPage GetPage(int pageNumber)
        {

            DocumentPage page = ParentDocument.GetPage(pageNumber);
            ((ContainerVisual)page.Visual).Transform = _sTransform;
            return page;
        }

        public override bool IsPageCountValid
        {
            get {return ParentDocument.IsPageCountValid;}
        }

        public override int PageCount
        {
            get {return ParentDocument.PageCount;}
        }

        public override Size PageSize
        {
            get {return ParentDocument.PageSize;}
            set {ParentDocument.PageSize = value;}
        }

        public override IDocumentPaginatorSource Source
        {
            get {return ParentDocument.Source;}
        }
    }

PrintDialog printDialog;
printDialog.PrintDocument(fdp, "print");

When I use ((ContainerVisual)page.Visual).Transform = _sTransform;, an error is reported that the object of type "System.Windows.Documents.FixedPage" cannot be coerced to type "System.Windows.Media.ContainerVisual".
Please me how can i solve it

Developer technologies | Windows Presentation Foundation
{count} votes

Accepted answer
  1. Hui Liu-MSFT 48,676 Reputation points Microsoft External Staff
    2021-12-29T10:02:00.28+00:00

    I modified your GetPage method, it works for me, you could try it in your code.

    MainWindow.xaml:

    <StackPanel>  
            <Button x:Name="btn" Click="btn_Click" Content="click" Height="40"/>  
            <FlowDocumentPageViewer x:Name="content">  
                <FlowDocument >  
                    <BlockUIContainer>  
                        <Canvas x:Name="canvas">  
                            <TextBlock Text=" hello" />  
                            <TextBlock Text=" hello" Margin="0,30"/>  
                            <TextBlock Text=" hello" Margin="0,60"/>  
                        </Canvas>  
                    </BlockUIContainer>  
                </FlowDocument>  
            </FlowDocumentPageViewer>  
        </StackPanel>  
    

    MainWindow.xaml.cs:

    using System.Windows;  
    using System.Windows.Controls;  
    using System.Windows.Documents;  
    using System.Windows.Media;  
    namespace DocumentViewerzoom  
    {  
      public partial class MainWindow : Window  
      {  
        public MainWindow()  
        {  
          InitializeComponent();  
        }  
        private void btn_Click(object sender, RoutedEventArgs e)  
        {  
          DocumentPaginator doc = (content.Document).DocumentPaginator;  
          FittedDocumentPaginator fdp = new FittedDocumentPaginator(doc, 0.3);  
          PrintDialog printDialog = new PrintDialog();  
          printDialog.PrintDocument(fdp, "print");  
        }  
      }  
      public class FittedDocumentPaginator : DocumentPaginator  
      {  
        public DocumentPaginator ParentDocument { get; private set; }  
        public double Scale { get; private set; }  
        private readonly ScaleTransform _sTransform;  
        public FittedDocumentPaginator(DocumentPaginator baseDp, double scale)  
        {  
          if (baseDp == null)  
            return;  
          ParentDocument = baseDp;  
          Scale = scale;  
          _sTransform = new ScaleTransform(scale, scale); //Zoom  
    
        }  
        private DocumentPage CreatePage(Grid grid)  
        {  
          var box = this.SizingPageGrid(grid);  
          return new DocumentPage(grid, this.PageSize, box, box);  
        }  
        private Rect SizingPageGrid(Grid grid)  
        {  
          var box = new Rect(new Point(0, 0), this.PageSize);  
          grid.InvalidateArrange();  
          grid.UpdateLayout();  
          grid.Measure(this.PageSize);  
          grid.Arrange(box);  
          return box;  
        }  
        public override DocumentPage GetPage(int pageNumber)  
        {  
          DocumentPage page = ParentDocument.GetPage(pageNumber);  
    
          ContainerVisual newVisual = new ContainerVisual();  
          DrawingVisual pageVisual=page.Visual as DrawingVisual;  
          if(pageVisual != null&& pageVisual.Parent != null)  
          {  
            ContainerVisual parent = pageVisual.Parent as ContainerVisual;  
            parent.Children.Remove(pageVisual);  
          }  
          newVisual.Children.Add(page.Visual);  
          newVisual.Transform = _sTransform;  
          DocumentPage newPage=new DocumentPage(newVisual);  
          return newPage;  
        }  
        public override bool IsPageCountValid  
        {  
          get { return ParentDocument.IsPageCountValid; }  
        }  
        public override int PageCount  
        {  
          get { return ParentDocument.PageCount; }  
        }  
        public override Size PageSize  
        {  
          get { return ParentDocument.PageSize; }  
          set { ParentDocument.PageSize = value; }  
        }  
        public override IDocumentPaginatorSource Source  
        {  
          get { return ParentDocument.Source; }  
        }  
      }   
    }  
    

    The result:
    161107-4.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
     Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread. 

    [5]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.