我如何打印在Windows Store应用的WebView内容? [英] How do I print WebView content in a Windows Store App?

查看:173
本文介绍了我如何打印在Windows Store应用的WebView内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个地铁应用,我试图打印的WebView 控件的内容。使用 MSDN打印样张作为源引用。我只是修改 XAML printableArea 如下:

I have a Metro App and I am attempting to Print the Content of a WebView control. Using the MSDN Print Sample as my source reference. I simply change the XAML in the printableArea as follows:

    <RichTextBlock>
        <Paragraph>
            <InlineUIContainer>
                <WebView Width="800" Height="2000" Source="http://www.stackoverflow.com"/>
            </InlineUIContainer>
        </Paragraph>
    </RichTextBlock>

这部分工作。问题是,在指定的尺寸可见区域被打印出来,即可以滚动不打印,也该区域的不显示在为多页打印preVIEW

This works partially. The problem is that the Visible area in the specified dimensions is Printed, i.e. The area that can be scrolled does not Print and also does not show up as Multiple Pages in the PrintPreview.

我几乎没有,将AP preciate的一点点帮助得到这个正常工作。

I'm almost there, would appreciate a little bit of help to get this to work as expected.

我还没有发现任何地方的任何样本,解决这一特定问题。

I haven't found any samples anywhere, which tackle this specific problem.

我甚至试过这里的解决方案:<一href=\"http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/5edcb239-7a5b-49f7-87e3-e5a253b809c4\">http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/5edcb239-7a5b-49f7-87e3-e5a253b809c4

I have even tried the solutions here: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/5edcb239-7a5b-49f7-87e3-e5a253b809c4

我不是第一次经历过同样的/类似的问题:
<一href=\"http://social.msdn.microsoft.com/Search/en-US/?Refinement=112&query=print%20webview#refinementChanges=180&pageNumber=1&showMore=false\">http://social.msdn.microsoft.com/Search/en-US/?Refinement=112&query=print%20webview#refinementChanges=180&pageNumber=1&showMore=false

I am not the first to have experienced same/similar problem: http://social.msdn.microsoft.com/Search/en-US/?Refinement=112&query=print%20webview#refinementChanges=180&pageNumber=1&showMore=false

愿意给任何人谁可以解决这个问题,一个100点赏金。将AP preciate演练,样品code或模拟项目作为解决方案。

推荐答案

当然,在这里你去。

首先,你可以调整的WebView 来的实际内容。然后,缩放的WebView 回原来的大小。这将需要一个脚本中调用和 ScaleTransform 。 pretty简单,真的。

First, you can resize the WebView to the actual content. Then, you scale the WebView back to the original size. It would require a script invoke and a ScaleTransform. Pretty simple, really.

这样的:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <WebView x:Name="MyWebView" Source="http://www.stackoverflow.com" />
</Grid>

void MyWebView_LoadCompleted(object sender, NavigationEventArgs e)
{
    var _Original = MyWebView.RenderSize;

    // ask the content its width
    var _WidthString = MyWebView.InvokeScript("eval",
        new[] { "document.body.scrollWidth.toString()" });
    int _Width;
    if (!int.TryParse(_WidthString, out _Width))
        throw new Exception(string.Format("failure/width:{0}", _WidthString));

    // ask the content its height
    var _HeightString = MyWebView.InvokeScript("eval",
        new[] { "document.body.scrollHeight.toString()" });
    int _Height;
    if (!int.TryParse(_HeightString, out _Height))
        throw new Exception(string.Format("failure/height:{0}", _HeightString));

    // resize the webview to the content
    MyWebView.Width = _Width;
    MyWebView.Height = _Height;

    // scale the webview back to original height (can't do both height & width)
    var _Transform = (MyWebView.RenderTransform as ScaleTransform)
        ?? (MyWebView.RenderTransform = new ScaleTransform()) as ScaleTransform;
    var _Scale = _Original.Height / _Height;
    _Transform.ScaleX = _Transform.ScaleY = _Scale;
}

这将导致一个非常高的,狭窄的的WebView 是这样的:

This will result in a very tall, narrow WebView like this:

但是,这不是你想要的。

尽管你可以调整所产生的矩形,它不是那么疯狂的形状,在Windows 8打印合同要求您为它提供一个单一的页面。它不为你做的分页。这样一来,你真正需要的是获取个人网站,一次一个页面。

Even though you can resize the resulting rectangle so that it is not so crazy shaped, the Print Contract in Windows 8 requires that you provide it with a single page. It does not do the pagination for you. As a result, what you really need is to retrieve the individual web site, one page at a time.

第一种方法是如何做到这一点的基础。但是,你需要将矩形的大小固定在由Windows 8的打印任务传递给你的页面大小。这将根据用户的打印机选择。例如,信与A4(英国)。然后,用刷子的拉伸性能可以保证其自身作物。然后,使用变换刷属性,可将它向上和向下的矩形内则透露要打印的页面,直到

The first approach is the basis on how to do that. But you need to fix the size of the rectangle to the page size passed to you by Windows 8's Print task. This will be based on the user's printer selection. For example, Letter versus A4 (in UK). Then, using the Stretch property of the brush you can ensure it crops itself. Then, using the Transform property of the brush, you can slide it up and down inside the rectangle until it is revealing the page you want to print.

下面的方式:

<Grid Background="Blue">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="995" />
        <ColumnDefinition Width="300" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <WebView Grid.Column="0" x:Name="MyWebView" Source="http://www.stackoverflow.com" HorizontalAlignment="Right" />
    <Rectangle Grid.Column="1" x:Name="MyWebViewRectangle" Fill="Red" />
    <ScrollViewer Grid.Column="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <ItemsControl x:Name="MyPrintPages" VerticalAlignment="Top" HorizontalAlignment="Left">
            <Rectangle Height="150" Width="100" Fill="White" Margin="5" />
            <Rectangle Height="150" Width="100" Fill="White" Margin="5" />
            <Rectangle Height="150" Width="100" Fill="White" Margin="5" />
            <Rectangle Height="150" Width="100" Fill="White" Margin="5" />
            <Rectangle Height="150" Width="100" Fill="White" Margin="5" />
        </ItemsControl>
    </ScrollViewer>
</Grid>

public MainPage()
{
    this.InitializeComponent();
    MyWebView.LoadCompleted += MyWebView_LoadCompleted;
}

void MyWebView_LoadCompleted(object sender, NavigationEventArgs e)
{
    MyWebViewRectangle.Fill = GetWebViewBrush(MyWebView);
    MyPrintPages.ItemsSource = GetWebPages(MyWebView, new Windows.Foundation.Size(100d, 150d));
    MyWebView.Visibility = Windows.UI.Xaml.Visibility.Visible;
}

WebViewBrush GetWebViewBrush(WebView webView)
{
    // resize width to content
    var _OriginalWidth = webView.Width;
    var _WidthString = webView.InvokeScript("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 = webView.InvokeScript("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
    {
        SourceName = webView.Name,
        Stretch = Stretch.Uniform
    };
    _Brush.Redraw();

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

IEnumerable<FrameworkElement> GetWebPages(WebView webView, Windows.Foundation.Size page)
{
    // ask the content its width
    var _WidthString = webView.InvokeScript("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;

    // ask the content its height
    var _HeightString = webView.InvokeScript("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;

    // how many pages will there be?
    var _Scale = page.Width / _ContentWidth;
    var _ScaledHeight = (_ContentHeight * _Scale);
    var _PageCount = (double)_ScaledHeight / page.Height;
    _PageCount = _PageCount + ((_PageCount > (int)_PageCount) ? 1 : 0);

    // create the pages
    var _Pages = new List<Windows.UI.Xaml.Shapes.Rectangle>();
    for (int i = 0; i < (int)_PageCount; i++)
    {
        var _TranslateY = -page.Height * i;
        var _Page = new Windows.UI.Xaml.Shapes.Rectangle
        {
            Height = page.Height,
            Width = page.Width,
            Margin = new Thickness(5),
            Tag = new TranslateTransform { Y = _TranslateY },
        };
        _Page.Loaded += (s, e) =>
        {
            var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
            var _Brush = GetWebViewBrush(webView);
            _Brush.Stretch = Stretch.UniformToFill;
            _Brush.AlignmentY = AlignmentY.Top;
            _Brush.Transform = _Rectangle.Tag as TranslateTransform;
            _Rectangle.Fill = _Brush;
        };
        _Pages.Add(_Page);
    }
    return _Pages;
}

因此​​,用户界面​​将是这样的,在左栏是web视图,第二列(中)是所有功能于一身的像我们的第一个解决方案,第三个,是表示准备单独的页面转发器打印。

So the UI will be something like this, where the left column is the WebView, the second column (middle) is the all-in-one like our first solution, and the third, is a repeater showing the individual pages ready to print.

当然,神奇的是真正的GetWebPages()方法!我不介意说,这是一个简单的奇迹作出pretty轻松的方式C#和转换工作。

Of course the magic is really in the GetWebPages() method! I don't mind saying, it's a simple marvel made pretty easy by the way C# and Transforms work.

请注意,这就是未完成。是的,它打破了您需要的页面,但我不能确定你多么希望保证金页面上。所以需要调整很小,但我想提到它。这是$ C $ 98%C,你将需要向上突破的WebView和preP如果响应为PAGINATE事件Windows 8的打印任务。然后每次通过矩形给它的一个

Please note, this is not complete. Yeah, it breaks up the page for you, but I can't be sure how much margin you want on your page. So the required tweaking is tiny, but I wanted to mention it. This is 98% of the code you will need to break up a WebView and prep if for the Windows 8 Print Task in response for the paginate event. Then pass the rectangles to it one at a time.

说了这么多,这可能是最COM prehensive解决这个问题在互联网上。 :)

Having said that, this is probably the most comprehensive solution to this problem on the internet. :)

祝您好运!

这篇关于我如何打印在Windows Store应用的WebView内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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