Modifying page index after document load

Jan 30, 2012 at 1:00 PM
Edited Jan 30, 2012 at 1:00 PM

I'm working on a proof-of-concept that allows users to view documents from a database. We would like the viewer to function in such a way that it is possible to persist the current state of the viewer so that the document is in the same position the next time it is opened.

Currently I have been able to add functionality that stores and loads the viewmode but as soon as the document is loaded the page index is reset and there is no event that I can find that is raised after the document is loaded to allow me to set the page index to the persisted value.

So my question is, is there a recommended way of setting the page index as soon as the document is loaded? In addition is it possible to access the current position of the view as opposed to just the current page?

Coordinator
Jan 30, 2012 at 9:51 PM

Hi Martin,

Due to the asynchronous loading nature of Document Toolkit, assigning a page number or index doesn't have any effect until the Document is actually loaded. You'll need to wait until the document is available. You then also need to wait until the Document Viewer has actually rendered its scrollviewer with page containers before you can scroll to the correct page.

There is currently no good solution for waiting until the viewer has finished its initial render pass. You can use a workaround involving a timer. Yeah, total hack, and I know it's not ideal but it works. Here's what you need to do:

First wait for the document to be loaded by handling the datasource propertychanged event and then use a timer to delay invoke the page navigation.

this.DataSource.PropertyChanged += OnDataSourcePropertyChanged;

private void OnDataSourcePropertyChanged(object sender, PropertyChangedEventArgs e)
{
  if (e.PropertyName == "Document" && this.DataSource.Document != null) {
    // document loaded, defer navigate to page
    var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(50) };
    timer.Tick += (s, args) => {
      timer.Stop();
      // perform navigation
      this.Viewer.PageNumber = 10;
    };
    timer.Start();
  }
}

Furthermore the current page index and page number can be used to access the current position of the viewer, there are currently no other properties available. What do you need?


- Koen

Jan 31, 2012 at 4:35 PM

This is something I had considered but wanted to avoid as we can't guarantee that the users aren't going to put in large documents that may take some time to load but as this is the only option we will have to experiment with what kind of timing we can acceptably set it to.

As far as the page view goes, if a user wishes to zoom in on a table in their document and then save that view for the next session, then at the moment regardless of where the view was during the last session the view will be moved to the beginning of the page that they were looking at and so the table will no longer be visible. So ideally we would like to have more fine grained access to the viewer position than just the page.

In addition, I am also having issues setting the viewmode in the code behind. I am currently using the ViewModePicker and whenever I manually change the SelectedViewMode property this change is not reflected in the Picker even though it is accurately reflected in the view. If I change the selection in the Picker it also changes the view so it looks like the binding is working correctly. Could there be something I'm missing?

Coordinator
Jan 31, 2012 at 5:38 PM

Hi Martin,

I forgot to mention the DocumentViewer.BringIntoView methods that do provide finer grained control over positioning the viewer content. These are not properties, so direct binding won't work, but a behavior might help?

When setting the SelectedViewMode in code, make sure the ViewMode instance that you assign to the picker does exist in the ViewModes collection. 

- Koen