Maintain current position in document when rotating / zooming

2 posts, 0 answers
  1. Chris Johnson
    Chris Johnson avatar
    18 posts
    Member since:
    Feb 2006

    Posted 02 Mar Link to this post

    When the PDFViewer is using FixedDocumentPagesPresenter it tends to change position (it jumps to different pages) when a page is rotated and the same thing can also occur when zooming in/out.

    To see this, simply open any PDF with more than a few pages - the one I'm currently testing with has 18 pages, move away from the first few pages (e.g. go to page 12), and rotate the page. The position jumps several pages and is restored if you rotate 360 degs.  In my test doc, it jumps to page 16 when rotated 90 / 270 degrees and back to page 12 when rotated 0 / 180 degrees.

    There's a similar problem when zooming in, but I think you need a document with a few hundred pages to see this.

    It all seems to be fine when using FixedDocumentSinglePageViewPresenter.

    Any chance you can fix this?

    Thanks.

  2. Deyan
    Admin
    Deyan avatar
    166 posts

    Posted 07 Mar Link to this post

    Hello Chris Johnson,

    Current implementation preserves the scroll offsets when the pages are rotated. This way when you rotate all pages from a Portrait orientation to Landscape for instance, then the sum of rotated heights gets smaller and with the same scroll offset you see pages with a higher page number. You may easily change the default implementation by implementing custom command descriptors. A sample implementation of such custom rotate commands may be seen below:
    public class CustomRotateCommand : FixedDocumentViewerCommandBase
    {
        private readonly ICommand defaultCommand;
     
        public CustomRotateCommand(FixedDocumentViewerBase viewer, ICommand defaultCommand)
            : base(viewer)
        {
            this.defaultCommand = defaultCommand;
        }
     
        public override void Execute(object parameter)
        {
            int pageNumber = this.Viewer.CurrentPageNumber;
            this.defaultCommand.Execute(parameter);
     
            IFixedDocumentPresenter presenter = this.Viewer.FixedDocumentPresenter;
            Control presenterControl = (Control)presenter;
            presenterControl.UpdateLayout();
            presenter.GoToPage(pageNumber);
        }
    }
     
    public class CustomCommandDescriptors : DefaultCommandDescriptors
    {
        private readonly CommandDescriptorBase customRotateClockwiseDescriptor;
        private readonly CommandDescriptorBase customRotateCounterClockwiseDescriptor;
     
        public CustomCommandDescriptors(FixedDocumentViewerBase viewer)
            : base(viewer)
        {
            FixedDocumentViewerCommandBase customRotateClockwiseCommand = new CustomRotateCommand(viewer, viewer.CommandDescriptors.RotateClockwiseCommandDescriptor.Command);
            FixedDocumentViewerCommandBase customRotateCounterClockwiseCommand = new CustomRotateCommand(viewer, viewer.CommandDescriptors.RotateCounterClockwiseCommandDescriptor.Command);
     
            this.customRotateClockwiseDescriptor = new CommandDescriptor(customRotateClockwiseCommand);
            this.customRotateCounterClockwiseDescriptor = new CommandDescriptor(customRotateCounterClockwiseCommand);
        }
     
        public override CommandDescriptorBase RotateClockwiseCommandDescriptor
        {
            get
            {
                return this.customRotateClockwiseDescriptor;
            }
        }
     
        public override CommandDescriptorBase RotateCounterClockwiseCommandDescriptor
        {
            get
            {
                return this.customRotateCounterClockwiseDescriptor;
            }
        }
    }

    The command descriptors may be set to RadPdfViewer instance after InitializeComponent() method call as shown in the snippet below:
    this.pdfViewer.CommandDescriptors = new CustomCommandDescriptors(this.pdfViewer);

    I hope this is helpful.

    Regards,
    Deyan
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Back to Top