locked
Print Charm "Preview" issue: possible OS defect?

    Question

  • Hello-

    Been experimenting around with the Print Sample SDK code for C# (http://code.msdn.microsoft.com/windowsapps/Print-Sample-c544cce6).    We are specifically interested in the Print Charm flow, however, we find that the print preview fails to render any of the PNG (or JPG) images on the first time the preview is shown.  If you dismiss the preview and display it again, the images display successfully.   This is happening with the latest VS 11 tools and CP build.   Note that even when the preview fails to show the images, they print successfully.

    We want to leverage this code for a app we are developing, but the failure to render images on the first preview is a deal breaker.   

    We have been experimenting around with this code, and have found the *only* workaround to this is to do the following steps *prior* to the Paginate() callback:

                // Assumes that you have a test/scan.jpg file deployed in the installation

                StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///test/scan.jpg"));
                _b = new BitmapImage();
                _b.SetSource(await file.OpenReadAsync());

    The SetSource() call will trigger the background decoding and rendering of the Bitmap such that it is available to display at first preview.  NOTE that if you try to do this sequence from within the Paginate() callback, it will fail as well.

    A workaround, albeit very poor, would be to create the BitmapImages prior to the print charm callback.  This would be memory intensive and wasteful if the user never decides to actually print...

    Is this a known OS issue?

    THanks in advance

    Jeremy

    Wednesday, April 18, 2012 9:38 PM

Answers

  • After creating content "on the fly" during the Paginate event, there is a chance due to a timing issue that images are not rendered in the very first page preview. More specifically, images will not be completely loaded after the Paginate event and so they might not be ready in time for the GetPreviewPage event. This can be extended to any element that loads its content asynchronously and is added “on the fly” during Paginate event.

    The flow is the following:

    Once Paginate event completes, preview will ask for content to display (GetPreviewPage event). At this point, the content created during Paginate might not be ready. To address this issue elegantly an application might choose to maintain a state for each page and do one of the following when asked for content during GetPreviewPage event:

    • Wait in GetPreviewPage event handler until the requested page is ready (images and other elements are fully loaded)
    • Use a multi stage update: serve the page “as it is” and later, when the page is ready or when an element within the page is completely loaded, update the page preview content by calling again SetPreviewPage.

    As an example in the given context: listen for ImageOpened events for every Image on each page and once all events fire for a given page, that page can be considered to be ready.

    Monday, May 14, 2012 7:59 PM

All replies

  • I will look into this for you.  Best Wishes - Eric
    Thursday, April 19, 2012 5:05 PM
    Moderator
  • After creating content "on the fly" during the Paginate event, there is a chance due to a timing issue that images are not rendered in the very first page preview. More specifically, images will not be completely loaded after the Paginate event and so they might not be ready in time for the GetPreviewPage event. This can be extended to any element that loads its content asynchronously and is added “on the fly” during Paginate event.

    The flow is the following:

    Once Paginate event completes, preview will ask for content to display (GetPreviewPage event). At this point, the content created during Paginate might not be ready. To address this issue elegantly an application might choose to maintain a state for each page and do one of the following when asked for content during GetPreviewPage event:

    • Wait in GetPreviewPage event handler until the requested page is ready (images and other elements are fully loaded)
    • Use a multi stage update: serve the page “as it is” and later, when the page is ready or when an element within the page is completely loaded, update the page preview content by calling again SetPreviewPage.

    As an example in the given context: listen for ImageOpened events for every Image on each page and once all events fire for a given page, that page can be considered to be ready.

    Monday, May 14, 2012 7:59 PM
  • I will try this, but in general this seems like a lot of unnecessary burden for callback/app.  

    Another related question.. is there a reason why the PaginateEventArgs and/or GetPreviewPageEventArgs classes don't provide any Deferral calls... which makes doing any Async work in the callback extremely difficult, and inefficient.  Other charms (such as share) offer the deferral such that async work in the callback can be done easily.

    Thanks

    Jeremy

    Wednesday, May 23, 2012 7:56 PM