如何等待 WebViewBrush.Redraw() 完成(UWP 打印)? [英] How to wait for WebViewBrush.Redraw() to finish (UWP printing)?

查看:65
本文介绍了如何等待 WebViewBrush.Redraw() 完成(UWP 打印)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本的 UWP 应用程序,其中嵌入了一个 WebView 来呈现一个相当大的 HTML 文档(最多 500 个字母大小的打印页面).

I have a basic UWP app with an embedded WebView presenting a rather large HTML document (up to 500 letter-sized printed pages).

我想添加对打印该 HTML 文档的支持.这是我的方法:

I'd like to add support for printing that HTML document. Here is my approach:

  1. 为了支持分页,我通过对每个页面"使用 <div style="height:100vh"> 生成了一个分成页面"的第二个 HTML 文档,最多 500 个这些.
  2. 我将分页"HTML 加载到 XAML 页面上的第二个隐藏 WebView 中,我根据用户选择的页面大小调整了该页面的大小以恰好适合一个页面.
  3. 我等待 WebView 完成加载...
  4. 现在对于每个页面":
  1. 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.
  2. 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.
  3. I wait for the WebView to finish loading...
  4. Now for each "page":
  1. 我将 WebView 的 scrollY 设置为使用 JavaScript 仅显示当前页面:window.scrollTo(0, -pageOffset)
  2. 然后我使用 WebViewBrushWebView
  3. 中捕获当前页面的快照
  4. 对所有剩余页面重复此操作...
  1. I set the WebView's scrollY to show only the current page using JavaScript: window.scrollTo(0, -pageOffset)
  2. I then use WebViewBrush to capture a snapshot of the current page in the WebView
  3. Repeat this for all remaining pages...

问题:

我可以生成所有 500 页的打印预览,但有时预览缺少页面而其他页面显示多次.

I can generate the print preview of all 500 pages, but sometimes the preview is missing pages while other pages show up multiple times.

我怀疑这是因为我使用 WebViewBrush.Redraw() 来捕获滚动的 WebView 的快照,但文档说 Redraw() 异步发生.我可能会在 WebViewBrush 有机会重绘之前滚动到当前页面,因此不小心捕获了下一页.

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.

如何确保 WebViewBrush 已捕获 WebView 以便我可以滚动到下一页?

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;
    }

注意:如果有使用 WebViewBrush 打印 500 页的替代方法,我愿意提供建议.我尝试为每个页面使用单独的 WebView,但应用在 200 个页面后内存不足.

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.

悬赏:我开始悬赏悬赏,向能够弄清楚如何打印 500 页的任何人提供 100 积分.

BOUNTY: I started a bounty offering 100 points to anybody who can figure out how to print 500 pages.

推荐答案

根据 WebViewBrush 备注:

According to the Important section of the WebViewBrush remarks:

WebView 控件具有固有的异步行为,它会在其内容完全加载时重绘控件.但是,一旦解析 XAML(这可能在 WebView 加载 URI 内容之前),关联的 WebViewBrush 就会呈现.或者,您可以等待在源内容完全加载之前调用 WebViewBrush 上的 SetSource(例如,通过在 WebView.LoadCompleted 事件的处理程序中调用 SetSource.

A WebView control has an inherently asynchronous behavior that redraws the control when its content is completely loaded. But an associated WebViewBrush renders as soon as the XAML is parsed (which might be before the URI content is loaded by the WebView ). Alternatively, you can wait to call SetSource on the WebViewBrush until the source content is fully loaded (for example by calling SetSource in the handler for the WebView.LoadCompleted event.

以便您可以在 WebView.LoadCompleted.

So that you could calling SetSource method of WebViewBrush after WebView.LoadCompleted.

这篇关于如何等待 WebViewBrush.Redraw() 完成(UWP 打印)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆