如何等待WebViewBrush.Redraw()完成(UWP打印)?

Mar*_*ark 8 printing webview windows-10 uwp uwp-xaml

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

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

  1. 为了支持分页,我生成第二个HTML文档,分为"页面" <div style="height:100vh">,每个"页面" 使用一个,最多500个.
  2. 我将"分页"HTML加载到WebViewXAML页面上隐藏的第二个,我根据用户选择的页面大小调整大小以适合一页.
  3. 我等待WebView完成加载......
  4. 现在为每个"页面":
    1. 我将WebView设置为scrollY仅使用JavaScript显示当前页面:window.scrollTo(0, -pageOffset)
    2. 然后我WebViewBrush用来捕获当前页面的快照WebView
    3. 对剩余的所有页面重复此操作...

问题:

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

我怀疑这是因为我WebViewBrush.Redraw()用来捕获滚动的WebView的快照,但文档说是Redraw() 异步发生的.我可能会在WebViewBrush有机会重绘之前滚动浏览当前页面,从而意外地捕获下一页.

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

我的代码生成一个页面:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

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

BOUNTY:我开始向任何可以弄清楚如何打印500页的人提供100分的赏金.

Sun*_* Wu 5

根据WebViewBrush评论的重要部分:

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

这样你就可以调用after SetSource方法了.WebViewBrushWebView.LoadCompleted