Xamarin.Forms UWP - 具有分页支持的打印 Web 视图

Posted

技术标签:

【中文标题】Xamarin.Forms UWP - 具有分页支持的打印 Web 视图【英文标题】:Xamarin.Forms UWP - Print Webview with pagination support 【发布时间】:2018-02-22 12:08:14 【问题描述】:

我正在开发基于 Xamarin.Forms 的项目,尝试使用分页打印 webview 内容。

我已经参考了以下链接: How do I print WebView content in a Windows Store App?

但不幸的是,这种方式不适用于 Xamarin.Forms,因为上述链接中演示的方式是使用 webviewbrush 填充矩形(窗口形状)(矩形和 webviewbrush 都是 UWP 的平台相关控件)。问题是我们不能使用 webviewbrush 来绘制矩形(Xamarin Forms 形状)。

作为一种解决方法,我执行了以下操作:

在 xamarin 表单 PCL 项目中创建了一个 boxview 在 UWP 项目中为此 boxview 创建了一个渲染器(这将为我们提供 windows 矩形形状),然后我确实将此矩形形状放入 PCL 项目的 App.cs 类中的公共静态属性之一,以使其可用于 Webviewrenderer .cs 类,用于使用 webviewbrush 填充此矩形。 我可以从 UWP 项目的 webviewrenderer.cs 类访问它,但问题是打印机对话框显示一个空白页面。 分页工作正常,如上面的堆栈溢出链接所示,但所有页面都是空的。

显然问题出在矩形上。因为如果我创建一个原生 UWP 项目并且打印机对话框也显示网页,那么同样的逻辑就可以正常工作。

任何帮助将不胜感激。

提前致谢!

【问题讨论】:

【参考方案1】:

分页工作正常,如上面的堆栈溢出链接所示,但所有页面都是空的。

我已经按照你的流程实现了基本的打印功能。我将GetWebViewBrush 方法放在webviewrenderer 中。不幸的是,同样的问题发生在我身边。

async Task<WebViewBrush> GetWebViewBrush(Windows.UI.Xaml.Controls.WebView webView)

    // resize width to content
    var _OriginalWidth = webView.Width;
    var _WidthString = await webView.InvokeScriptAsync("eval",
        new[]  "document.body.scrollWidth.toString()" );
    int _ContentWidth;

    if (!int.TryParse(_WidthString, out _ContentWidth))
        throw new Exception(string.Format("failure/width:0", _WidthString));

    webView.Width = _ContentWidth;

    // resize height to content
    var _OriginalHeight = webView.Height;

    var _HeightString = await webView.InvokeScriptAsync("eval",
        new[]  "document.body.scrollHeight.toString()" );
    int _ContentHeight;

    if (!int.TryParse(_HeightString, out _ContentHeight))
        throw new Exception(string.Format("failure/height:0", _HeightString));

    webView.Height = _ContentHeight;

    // create brush
    var _OriginalVisibilty = webView.Visibility;

    webView.Visibility = Windows.UI.Xaml.Visibility.Visible;

    var _Brush = new WebViewBrush
    
        Stretch = Stretch.Uniform,
        SourceName = webView.Name
    ;
  //  _Brush.SetSource(webView);

    _Brush.Redraw();

    // reset, return
    webView.Width = _OriginalWidth;
    webView.Height = _OriginalHeight;
    webView.Visibility = _OriginalVisibilty;
    return _Brush;

我在调试的时候发现webView.Name从来没有设置过值,所以我为customWebView新建了一个Name属性。

public static readonly BindableProperty NameProperty = BindableProperty.Create(
 propertyName: "Name",
 returnType: typeof(string),
 declaringType: typeof(MyWebView),
 defaultValue: default(string));

     public string Name
     
         get  return (string)GetValue(NameProperty); 
         set  SetValue(NameProperty, value); 
     

 

并在OnElementChanged方法中使用以下代码设置本机控件(Windows.UI.Xaml.Controls.WebView)的Name属性。

if (e.NewElement != null)

    Control.Name = (Element as MyWebView).Name;
    Control.NavigationCompleted += Control_NavigationCompleted;

令人惊讶的是,页面不再是空的。

【讨论】:

太棒了!这就像一个魅力!非常感谢:) OP 或@Nico (Zhu - MSFT)——你能分享你的完整解决方案吗,或者至少是什么?我正在尝试将这篇文章与引用的文章结合起来,但我无法知道将内容放在哪里,例如 PCL 视图中的内容(我使用的是 C#,而不是 XAML)以及特定于平台的内容(UWP)自定义渲染器。

以上是关于Xamarin.Forms UWP - 具有分页支持的打印 Web 视图的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 Xamarin.Forms UWP 应用程序的强调色?

Xamarin.Forms.UWP 数字键盘仅在软键盘上

Xamarin.Forms (UWP) - 如何获取 WebView 的 DOM 作为 HTML 字符串?

Xamarin.Forms UWP UI 测试

Xamarin.Forms.Picker 内容在 UWP 中重复

Xamarin.Forms:UWP 应用的本地化