UPDATE 3
现在有一个关于此问题的赏金。示例项目和问题摘要位于TL,DR;为自己节省一些阅读并跳到最后!从Windows应用商店应用中的WebView打印静态内容
...
我一直在试图摆脱JerryNixon通过NavigateToString使用静态页面加载这个工作非常详细,upvoted答案。我不明白为什么这不应该起作用,但不可否认的是,部分代码让我感到困惑。
原来的答案是here但我会在这里复制代码为完整起见。杰里提供了以下样品/解决方案,谁想要从WebView
<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视图的Source
属性,这行添加到MainPage()
方法
var html = await Windows.Storage.PathIO.ReadTextAsync("ms-appx:///Assets/sherlock.html");
MyWebView.NavigateToString(html);
Sherlock.html是Arthur Conan Doyle故事的摘录,红头联盟,此HTML页面的完整代码是here - 请注意,接近结尾的部分重复多次。这是在测试中完成的,我将在下面解释
本示例最初为我工作,在一个小文件上。 (Sherlock.html没有填充章节)
但是,当我获得超过某个文件大小(通常大约4000字+)时,样本发生以下行为。
的WebView中收缩到一个非常狭隘的观点
(明白为什么这个被剔除更新笔记)
,然后屏幕变成灰色。 (我觉得有点傻发布一个灰色的屏幕截图,但我想彻底这里)
应用程序不崩溃。没有调试消息出现,不会发生异常。
就好像
。这不是闪屏(我已经设置蓝色),它不是应用程序背景(深灰色)。就好像在页面的顶部加载了其他内容。Grid
被简单地移除一样。
我试过调整代码的每一部分,但我似乎无法隔离是什么原因造成的问题。此外,这些代码的一部分只是混淆了我的地狱。例如,在Load_Completed
方法
MyWebViewRectangle.Fill = GetWebViewBrush(MyWebView);
MyPrintPages.ItemsSource = GetWebPages(MyWebView, new Windows.Foundation.Size(100d, 150d));
MyWebView.Visibility = Windows.UI.Xaml.Visibility.Visible;
线路1:MyWebViewRectangle
充满WebView
的一个镜头。为什么?这个控制从不再被引用。我想这可能是用户得到的页面更清晰的视野,但它似乎起不到任何编程目的
3号线:MyWebView.Visibility
设置为Visible
再次出现这种情况后,在GetWebViewBrush
。
var _OriginalVisibilty = webView.Visibility;
webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
// and a few lines later...
webView.Visibility = _OriginalVisibilty;
据我所知道的,网页流量是从不Collapsed
,但它设置为Visible
三次。
如果任何人都可以向我解释任何这个(也许甚至是杰里尼克森自己?)我会真的欣赏它。我花了好几个月的时间研究一个应用程序,这是最后一块难题。如果没有打印能力,我无法启动!
UPDATE
今天早上做了一些发现。我一直在XAML中设置WebView
的宽度。没有这个,即使最小的文件都失败了。根据这个发现,我将HTML文件本身的宽度设置为800px,并且它工作正常。万岁,问题解决了吧?很不幸的是,不行。我再次尝试用更长的文件(完整版本红头发的联盟,here)并且同样的问题再次发生。它现在得到了很多怪物。
我在GetWebPages方法中插入了一个断点webView.Height = _ContentHeight;
。这表明我_ContentHeight完全是“13241”。
但是,插入断点的使代码工作。一旦我打破并继续,这一切似乎加载。虽然奇怪,WebView是隐藏的,直到我将鼠标悬停在滚动条上。
如果我删除断点,我再次看到灰色屏幕。
如果我手动将_ContentHeight
设置为13230,则会加载页面。这似乎是神奇的数字。任何高于此的内容都会失败。但是,如果我将html的宽度更改为小于800像素,它也会失败。因此逻辑上,800:13230像素(或1:16.5375)具有某种魔术比例。如果我超过这个比例,我就开始了死亡的灰色屏幕。我可以禁用红色矩形并将GetWebPages
限制为3页,灰色屏幕仍然存在。这告诉我,问题是WebView
本身
如果我设置了断点,这个问题就会消失。
还要注意在MyWebViewRectangle
和额外的空白页的多余的空格中MyPrintPages
时,它的工作:
注:我还添加事件LongRunningScriptDetected
,UnsafeContentWarningDisplaying
的NateDiamond的建议,并UnviewableContentIdentified
以下是我的示例项目的完整源代码: https://onedrive.live.com/redir?resid=EE99EF9560A6740E!110509&authkey=!ACrZgm6uq5k5yck&ithint=file%2czip
更新2
一些成功。
我把一些头文件放到我的示例文件中(通过试验和错误找到每个计算页面的“底部”),并调整页面大小以便可以看到标记。尽管有9页,但只有5页和6页的一小部分被渲染。 9页面对象由GetWebPages
创建,但只有5ish已呈现HTML内容。其余的都是空
(注意,我改变了背景颜色为蓝色,红色是给我一个偏头痛)
我已经通过代码消失了,做了一些修改,现在我不再得到灰色屏幕。然而,每3次运行一次,只有第一页被渲染,并被裁剪。这似乎完全是随机的。如所述,当9页提供时并不是全部都有内容。
这里是我的变化:
增加了新的方法Resize_WebView()
public void ResizeWebView()
{
OriginalHeight = MyWebView.Height;
var _WidthString = MyWebView.InvokeScript("eval", new[] { "document.body.scrollWidth.toString()" });
int _ContentWidth;
if (!int.TryParse(_WidthString, out _ContentWidth))
throw new Exception(string.Format("failure/width:{0}", _WidthString));
MyWebView.Width = _ContentWidth;
// ask the content its height
var _HeightString = MyWebView.InvokeScript("eval", new[] { "document.body.scrollHeight.toString()" });
int _ContentHeight;
if (!int.TryParse(_HeightString, out _ContentHeight))
throw new Exception(string.Format("failure/height:{0}", _HeightString));
MyWebView.Height = _ContentHeight;
}
在MyWebView_LoadCompleted
注释掉矩形填充,添加调用ResizeWebView():
void MyWebView_LoadCompleted(object sender, NavigationEventArgs e)
{
ResizeWebView();
//MyWebViewRectangle.Fill = GetWebViewBrush(MyWebView);
MyPrintPages.ItemsSource = GetWebPages(MyWebView, new Windows.Foundation.Size(300d, 450d));
}
在GetMyWebPages
改变地方刷子被加载:
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;
// Manually set _ContentHeight: comment out the above block and uncomment this to test.
// int _ContentHeight = 13230;
// webView.Height = _ContentHeight;*/
// how many pages will there be?
//var _Scale = page.Width/_ContentWidth;
var _Scale = page.Width/webView.Width; // now sourced directly from webview
//var _ScaledHeight = (_ContentHeight * _Scale);
var _ScaledHeight = (webView.Height * _Scale); // now sourced directly from webview
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 },
};
var _Brush = GetWebViewBrush(webView);
_Brush.Stretch = Stretch.UniformToFill;
_Brush.AlignmentY = AlignmentY.Top;
_Brush.Transform = _Page.Tag as TranslateTransform;
_Page.Fill = _Brush;
/*_Page.Loaded += async (s, e) =>
{
var _Rectangle = s as Windows.UI.Xaml.Shapes.Rectangle;
var _Brush = await GetMyWebViewBrush(webView);
_Brush.Stretch = Stretch.UniformToFill;
_Brush.AlignmentY = AlignmentY.Top;
_Brush.Transform = _Rectangle.Tag as TranslateTransform;
_Rectangle.Fill = _Brush;
};*/
_Pages.Add(_Page);
}
return _Pages;
}
从GetWebView
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;
}
这正在成为一个严重的问题史诗现在去掉不必要的调整大小代码。
TL; DR;
加载并观察。文档中有9个页面。
- GetWebPages偶尔只加载一个页面,裁剪
- 的其余时间,GetWebPages负荷1-5页,第6个3
空白页部分这是几乎所有你需要知道回答这个问题。
我已经在这个问题上给了一个赏金。我正在寻找这个问题的解决方法,并且如果可能的话,为每个页面添加填充以便文本不会运行到边缘。
在Windows 8.1有一堆成功和失败状态,如LongRunningScriptDetected,UnsafeContentWarningDisplaying和UnviewableContentIdentified事件。尝试添加这些事件并查看是否有火灾。另一种尝试是新的['NavigateToLocalStreamUri'](http://msdn.microsoft.com/en-US/library/windows/apps/windows.ui.xaml.controls.webview.navigatetolocalstreamuri.aspx)方法。 – 2014-09-29 22:22:08
谢谢Nate。我只是添加了所有这些事件,并为每个事件添加了一个“抛出新的异常......”。没有例外。再次,只是一个灰色的屏幕。我证实这不是网格也被删除 - 我的页面背景颜色是灰暗的。这灰色是“应用程序启动”灰色。 – roryok 2014-09-30 07:17:33
你在不同尺寸的屏幕上试过了吗?尝试在不同大小的屏幕模拟器中加载它,看看是否改变了数字。 – 2014-09-30 18:48:24