Xamarin.Forms UWP - печать веб-страниц с поддержкой разбивки на страницы

Я работаю над проектом на основе Xamarin.Forms, пытаясь распечатать содержимое веб-просмотра с разбивкой на страницы.

Я уже ссылался на следующую ссылку: Как распечатать содержимое WebView в приложении Windows Store?

Но, к сожалению, этот способ не работает с Xamarin.Forms, потому что способ, продемонстрированный в приведенной выше ссылке, заключается в заполнении прямоугольника (формы окна) с помощью webviewbrush (и прямоугольник, и webviewbrush являются элементами управления, зависящими от платформы для UWP). Проблема в том, что мы не можем использовать webviewbrush для рисования прямоугольника (форма Xamarin Forms).

В качестве обходного пути я сделал следующее:

  • создал boxview в проекте PCL форм xamarin
  • создал средство визуализации для этого окна в проекте UWP (это даст нам форму прямоугольника окна), а затем я поместил эту форму прямоугольника в одно из общедоступных статических свойств в классе App.cs проекта PCL, чтобы сделать его доступным для класса Webviewrenderer.cs для заполнения этого прямоугольника webviewbrush.
  • Я могу получить к нему доступ из класса webviewrenderer.cs из проекта UWP, но проблема в том, что в диалоговом окне принтера отображается пустая страница.
  • Пагинация работает нормально, как показано в приведенной выше ссылке на переполнение стека, но все страницы пусты.

Видимо проблема будет с прямоугольником. Поскольку та же самая логика просто отлично работает, если я создаю собственный проект UWP, и в диалоговом окне принтера также отображается веб-страница.

Любая помощь приветствуется.

Заранее спасибо!


person Viaan Hrithik    schedule 13.09.2017    source источник


Ответы (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 никогда не устанавливалось значение, поэтому я создаю новое свойство Name для customWebView.

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

 }

И установите свойство Name собственного элемента управления (Windows.UI.Xaml.Controls.WebView) с помощью следующего кода в методе OnElementChanged.

if (e.NewElement != null)
{
    Control.Name = (Element as MyWebView).Name;
    Control.NavigationCompleted += Control_NavigationCompleted;
}

Удивительно, но страница уже не пуста. введите здесь описание изображения

person Nico Zhu - MSFT    schedule 14.09.2017
comment
Чудесно! Это работает как шарм !! Большое спасибо :) - person Viaan Hrithik; 18.09.2017
comment
OP или @Nico (Zhu - MSFT) - не могли бы вы поделиться своим полным решением или, по крайней мере, что и куда? Я пытаюсь объединить этот пост с упомянутым, но у меня возникают проблемы с пониманием того, где разместить вещи, например, что идет в представлении PCL (я использую C #, а не XAML) и что происходит в конкретной платформе (UWP) пользовательский рендерер. - person jbyrd; 17.04.2018