I have a basic UWP app with an embedded WebView presenting a rather large HTML document (up to 500 letter-sized printed pages).
I'd like to add support for printing that HTML document. Here is my approach:
- To support pagination, I generate a second HTML document broken into "pages" by using a
<div style="height:100vh">
for each "page", up to 500 of these. - I load that "paginated" HTML into a second, hidden
WebView
on the XAML page that I resize to fit exactly one page based on the user selected page size. - I wait for the WebView to finish loading...
- Now for each "page":
- I set the WebView's
scrollY
to show only the current page using JavaScript:window.scrollTo(0, -pageOffset)
- I then use
WebViewBrush
to capture a snapshot of the current page in theWebView
- Repeat this for all remaining pages...
- I set the WebView's
The problem:
I can generate the print preview of all 500 pages, but sometimes the preview is missing pages while other pages show up multiple times.
I suspect this is because I use WebViewBrush.Redraw()
to capture a snapshot of the scrolled WebView, but the documentation says Redraw()
happens asynchronously. I may scroll past the current page before WebViewBrush gets a chance to redraw, hence accidentally capturing the next page.
How can I make sure that WebViewBrush has captured the WebView so that I can scroll to the next page?
My code to generate a single page:
private async Task<Rectangle> MakePage(WebView webView,
Size pageSize, double pageOffset)
{
// Scroll to next page:
await webView.EvaluateJavaScriptSnippetAsync(
$"window.scrollTo(0, {pageOffset})");
var brush = new WebViewBrush();
brush.Stretch = Stretch.Uniform;
brush.SetSource(webView);
brush.Redraw(); // XXX Need to wait for this, but there's no API
// Add a delay hoping Redraw() finishes... I think here is the problem.
await Task.Delay(150);
var rectangle = new Rectangle()
{
Width = pageSize.Width,
Height = pageSize.Height
};
rectangle.Fill = brush;
brush.Stretch = Stretch.UniformToFill;
brush.AlignmentY = AlignmentY.Top;
return rectangle;
}
Note: If there's an alternative to using WebViewBrush to print 500 pages, I'm open for suggestions. I tried using a separate WebView for each page, but the app runs out of memory after 200 pages.
BOUNTY: I started a bounty offering 100 points to anybody who can figure out how to print 500 pages.