1、Navigate to a url:
操作截图:
在文本框中输入网址,按回车:
结果:
页面的 xaml :
<TextBox x:Name="Address" Margin="0,0,10,0" KeyUp = "Address_KeyUp"/>// 接收回车事件 <ProgressRing x:Name="ProgressRing1" Height="50" Width="50"/> <Button x:Name="Navigate" Content="Navigate" Margin="0,0,10,0" Click="NavigateButton_Click"/>
相应的 C# :
private void NavigateButton_Click(object sender, RoutedEventArgs e) { ProgressRing1.IsActive = true; WebView1.LoadCompleted += new Windows.UI.Xaml.Navigation.LoadCompletedEventHandler(
WebView1_LoadCompleted); // 导航到一个指定的 URI。注意:如果是一个错误的格式, //会引发 FormatException,需要抓住这个异常 try { Uri targetUri = new Uri(Address.Text); WebView1.Navigate(targetUri); } catch (FormatException myE) { // Bad address } }
//浏览器完全加载 void WebView1_LoadCompleted(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e) { ProgressRing1.IsActive = false; } //当文本框有焦点时,接收回车事件 void Address_KeyUp(object sender, KeyRoutedEventArgs e) { if (e.Key == Windows.System.VirtualKey.Enter) { NavigateButton_Click(this, new RoutedEventArgs()); } }
2、Load HTML:
加载 HTML 字符串到 WebView 控件中:
操作截图:
点击上面的按钮,结果:
页面的 xaml :
//显示 html 字符串 <TextBox x:Name="HTML2" AcceptsReturn="True"/> //解析 html <WebView x:Name="WebView2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
相应的 C# :
protected override void OnNavigatedTo(NavigationEventArgs e) { string htmlFragment = @"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html> <head> <title>Map with valid credentials</title> <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/> <script type='text/javascript'
src='http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0'>
</script>
<script type='text/javascript'> var map = null; function getMap() { map = new Microsoft.Maps.Map(document.getElementById('myMap'),
{credentials: 'Your Bing Maps Key'}); } </script> </head> <body οnlοad='getMap();'> <div id='myMap' style='position:relative; width:400px; height:400px;'></div> </body> </html>;"; // 显示 html 字符串 HTML2.Text = htmlFragment; }
//点击按钮 ,浏览器解析 html private void Load_Click(object sender, RoutedEventArgs e) { WebView2.NavigateToString(HTML2.Text); }
3、Interact with script:
本实例演示怎样调用 WebView 控件中的脚本。
操作截图:
按钮
点击 “Load HTML ” 按钮:
点击 “Fire script” 按钮:
//加载 html 字符串 <Button x:Name="Load" Content="Load HTML" Margin="0,0,10,0" Click="Load_Click" /> //调用脚本中的方法 <Button x:Name="Script" Content="Fire script" Margin="0,0,10,0" Click="Script_Click" />
//显示 html 字符串 <TextBox x:Name="HTML3" TextWrapping="Wrap" AcceptsReturn="True"/> //解析 html <WebView x:Name="WebView3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
相应的 C# :
protected override void OnNavigatedTo(NavigationEventArgs e) { // 在 HTML 字符串中添加将被调用的 脚本 string htmlFragment = @" <html> <head> <script type='text/javascript'> function SayGoodbye() { document.getElementById('myDiv').innerText = 'GoodBye'; } </script> </head> <body> <div id='myDiv'>Hello</div> </body> </html>"; HTML3.Text = htmlFragment; }
private void Load_Click(object sender, RoutedEventArgs e) { // 解析 html WebView3.NavigateToString(HTML3.Text); } private void Script_Click(object sender, RoutedEventArgs e) { // 调用 WebView 中的 javascript 方法 'SayGoodbye' WebView3.InvokeScript("SayGoodbye", null); }
4、Using ScriptNotify:
有时候你需要 WebView 向应用传递数据。比如你使用脚本发回数据。你可以接管应用中
ScriptNotify 事件,然后再脚本中,你使用 window.external.nofity("return value"),这个
“return value” 就是你传递回来的值了。
如果你使用 NavigateToString 方法向 WebView 中加载脚本,然后你可以自动通过这个
ScriptNofity 事件得到返回的结果。
如果你通过使用导航到某个 URL 来加载脚本,你必须设置 WebView 控件中的这个 AllowedScriptNotifyUris 属性。这个属性是这个应用信任的一个 URIs 的列表,并且允许
通过这个列表中的 URL 加载的脚本发送数据。
操作截图:
当选择 "Using ScriptNotify" 时:
点击按钮,输出结果:
当选择 Using Navigate 时,点击 按钮:
页面的 xaml :
//导航到字符串
<RadioButton x:Name="NavToString" Content="Use NavigateToString" GroupName="MethodType" Click="NavToString_Click"/>
//导航到 URI
<RadioButton x:Name="Nav" Content="Use Navigate" Click="Nav_Click" GroupName="MethodType"/>
//调用脚本
<Button x:Name="FireScript" Content="Fire Script" Click="FireScript_Click"/>
显示结果:
<TextBox x:Name="HTML4" TextWrapping="Wrap" AcceptsReturn="True"/> <WebView x:Name="WebView4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ScriptNotify = "WebView4_ScriptNotify"/>
相应的 C# :
//导航到包含脚本的字符串 private void NavToString_Click(object sender, RoutedEventArgs e) { string htmlFragment = @" <html> <head> <script type='text/javascript'> function SayGoodbye() { window.external.notify('GoodBye'); } </script> </head> <body> Page with 'Goodbye' script loaded. Click the 'Fire Script'
button to run the script and send data back to the application. </body> </html>"; // 在一个 TextBox 中显示字符串,然后加载到 WebView 中 HTML4.Text = htmlFragment; WebView4.NavigateToString(HTML4.Text); }
//导航到一个 URI private void Nav_Click(object sender, RoutedEventArgs e) { WebView4.Navigate(new System.Uri("http://www.bing.com")); }
//当 WebView 引发 ScriptNotify 事件时触发 void WebView4_ScriptNotify(object sender, NotifyEventArgs e) { //浏览器返回的结果: e.Value string result = string.Format("Response from script: '{0}'", e.Value; }
private void FireScript_Click(object sender, RoutedEventArgs e) { if (NavToString.IsChecked == true) { //因为浏览器信任自身内容的脚本,所以当运行脚本,可以使用 //window.external.notify() 方法向应用返回数据 WebView4.InvokeScript("SayGoodbye", null); } else { if (Nav.IsChecked == true) { //这里我们必须设置 AllowedScriptNotifyUri //属性,以使浏览器信任列表中的 URI 返回的数据 List<Uri> allowedUris = new List<Uri>(); allowedUris.Add(new Uri("http://www.bing.com")); WebView4.AllowedScriptNotifyUris = allowedUris; //因为我们导航到的 URI 中没有返回值的方法,所以我们使用 eval() //方法向页面中注入脚本,然后我们调用 window.external.notify() 方法 string[] args = { "window.external.notify('GoodBye');" }; WebView4.InvokeScript("eval", args); } } }
5、Accessing the DOM:
在 WebView 控件中直接支持的功能是有限的。但是,有时候你需要使用额外的功能,例如
你想获取加载到 WebView 中的文档的 DOM 树。在上一个实例中你已经看到可以使用 “eval”
通过 InvokeScript() 方法向 WebView 中注入脚本。
本示例演示怎样使用这个技术获得加载到 WebView 中的文档 DOM 中的元素。下面的页面
加载完成后,我们会从控件的 DOM 中得到 document.title 属性。
操作截图:
页面的 xaml :
<WebView x:Name="WebView5" LoadCompleted = "WebView5_LoadCompleted" ScriptNotify = "WebView5_ScriptNotify"/>
相应的 C# :
protected override void OnNavigatedTo(NavigationEventArgs e) { WebView5.Navigate(new Uri("http://baidu.com")); }
void WebView5_LoadCompleted(object sender, NavigationEventArgs e) { List<Uri> allowedUris = new List<Uri>(); allowedUris.Add(new Uri("http://baidu.com")); WebView5.AllowedScriptNotifyUris = allowedUris; string[] args = { "document.title;" }; //把脚本注入到浏览器中 string foo = WebView5.InvokeScript("eval", args); //获得加载到浏览器中文档的标题 string strTitle = String.Format("Title is: {0}", foo); } void WebView5_ScriptNotify(object sender, NotifyEventArgs e) { //获得方法的返回值 e.Value }
6、Using WebView Brush:
本实例演示如何使用 WebViewBrush。因为 WebView 控件呈现在自己的 HWND 中,所以你应用的内容不能
显示在 WebView 控件的上方。为了解决这个问题,使用一个 Rectangle 覆盖这个 WebView 控件,并且使用这个
WebViewBrush 填充到 Rectangle.Fill 属性。这将会复制 WebView 控件的内容到 rectangle 中,并且它不会覆盖
应用的其它内容。
选择下面 ComboBox 中的选项查看这个问题。单击 “Show the solution” 按钮查看当使用 WebViewBrush 时 ComboBox 怎么表现。
操作截图:
页面中的按钮:
当不单击按钮,展开 ComboBox ,展开的内容被浏览器覆盖:
单击按钮后,再展开 ComboBox, 内容没有被 WebView 覆盖 :
页面中的 xaml :
<Button x:Name="Solution" Content="Show the solution" Click="Solution_Click"/>
<ComboBox x:Name="ComboBox1" Height="50" Width="200" HorizontalAlignment="Left" Margin="10,0,0,0"> <ComboBoxItem> <x:String>First Item</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>Second Item</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>Third Item</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>Fourth Item</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>Fifth Item</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>Sixth Item</x:String> </ComboBoxItem> <ComboBoxItem> <x:String>Seventh Item</x:String> </ComboBoxItem> </ComboBox> <WebView x:Name="WebView6" /> <Rectangle x:Name="Rect1"/>
相应的 C# :
protected override void OnNavigatedTo(NavigationEventArgs e) { //注册 ComboBox 的展开事件 ComboBox1.DropDownOpened += ComboBox1_DropDownOpened; // 注册 收缩 事件 ComboBox1.DropDownClosed += ComboBox1_DropDownClosed; // 默认选择第一项 ComboBox1.SelectedIndex = 0; // 开始隐藏矩形对象 Rect1.Visibility = Windows.UI.Xaml.Visibility.Collapsed; WebView6.Navigate(new Uri("http://www.bing.com")); }
//单击按钮,显示矩形 private void Solution_Click(object sender, RoutedEventArgs e) { Rect1.Visibility = Windows.UI.Xaml.Visibility.Visible; } void ComboBox1_DropDownOpened(object sender, object e) { //如果矩形对象显示的时候,使用 WebViewBrush 画刷填充矩形 if (Rect1.Visibility == Windows.UI.Xaml.Visibility.Visible) { // 提供呈现当前在 WebView 控件中承载的内容的画笔。 WebViewBrush b = new WebViewBrush(); // 获取提供 HTML 内容的 WebView 源控件的名称。 b.SourceName = "WebView6"; // 强制画笔以异步方式重绘自身。 b.Redraw(); //获取或设置指定形状内部绘制方式的 Brush。 Rect1.Fill = b; WebView6.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } } void ComboBox1_DropDownClosed(object sender, object e) { WebView6.Visibility = Windows.UI.Xaml.Visibility.Visible; //清空矩形的填充 Rect1.Fill = new SolidColorBrush(Windows.UI.Colors.Transparent); }
7、Supporting the Share Contact:
通过 Share contract 协议,应用程序可以分享 WebView 控件中的内容。通过设置 WebView 控件的
DataTransferPackage 属性为 enabled 使它成为可能。当下面的页面加载完成,选择其中的部分内容,然后
点击 “Share Content” 按钮。
操作截图:
选择网页中的图片和文字:
点击 “Share Content ” 按钮,在弹出的列表中选择 Mail 选项:
页面的 XAML :
<Button x:Name="ShareContent" Content="Share Content" Click="Share_Click"/> <WebView x:Name="WebView7" Visibility="Collapsed"/> <Rectangle x:Name="BlockingRect"/> <ProgressRing x:Name="ProgressRing1" IsActive="true" Height="50" Width="50"/>
相应的 c# :
protected override void OnNavigatedTo(NavigationEventArgs e) { WebView7.LoadCompleted += WebView7_LoadCompleted; //加载网页 WebView7.Navigate(new Uri("http://www.baidu.com")); }
void WebView7_LoadCompleted(object sender, NavigationEventArgs e) { WebView7.Visibility = Windows.UI.Xaml.Visibility.Visible; BlockingRect.Visibility = Windows.UI.Xaml.Visibility.Collapsed; ProgressRing1.IsActive = false; }
//单击 分享 按钮后,执行分享操作 //通过其他应用程序以编程方式启动内容的交换。 DataTransferManager dataTransferManager = null; private void Share_Click(object sender, RoutedEventArgs e) { //返回与当前窗口关联的 DataTransferManager 对象。 dataTransferManager = DataTransferManager.GetForCurrentView(); //在共享操作开始时发生。 dataTransferManager.DataRequested += dataTransferManager_DataRequested; // 使用其他应用程序以编程方式启动用于共享内容的用户界面。 DataTransferManager.ShowShareUI(); } void dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { DataRequest request = args.Request;//让您可以获取 DataRequest 对象,并为其提供数据或失败消息。 // 获取传递给 WebView 的剪贴板 DataPackage。 DataPackage p = WebView7.DataTransferPackage; // p.GetView() : 返回 DataPackageView 对象。这是 DataPackage 对象的只读副本的对象。 //Contains() : 检查是否 DataPackageView 包含特定数据格式。 if (p.GetView().Contains(StandardDataFormats.Text)) { p.Properties.Title = "WebView Sharing Excerpt"; p.Properties.Description = "This is a snippet from the content hosted in the WebView control"; request.Data = p; } else { // 取消共享操作并提供错误字符串以显示给用户。 request.FailWithDisplayText("Nothing to share"); } dataTransferManager.DataRequested -= dataTransferManager_DataRequested; }
8、co-existing with the AppBar:
在第六个示例中讲到了,WebView 控件是通过他自己的 HWND 进行呈现的,因此有些问题出现了。
一个常见的场景是当年把 WebView 控件进行全屏显示的时候,你相应使用 AppBar。通常 XAML 元素不能
显示在 WebView 控件的上方。更重要的是,WebView 控件会接收 XAML 元素树中所有手势。
那么,WebView 控件和 AppBar 是否可以共存呢?
不幸的是,我们必须做出大量的工作才能实现。
你需要 接管 AppBar.Opened 事件,并且调整 WebView 的尺寸 以容纳 AppBar,然后移动
这个 WebView 控件来使用余下的屏幕显示 AppBar。
点击 “Show Me” 按钮,跳转到另一个页面,其中包含一个全屏的 WebView 控件和一个 AppBar。可以
使用手势滑动、右键单击 或者使用 Windows + Z 快捷键来显示 AppBar。
操作截图, 并显示 AppBar:
页面的 XAML :
<!--AppBar--> <Page.BottomAppBar> <AppBar x:Name="BottomBar"> <StackPanel Orientation="Horizontal" Background="#ff96ff63"> <Button x:Name="Home" Style="{StaticResource HomeAppBarButtonStyle}" Click="Home_Click"/> </StackPanel> </AppBar> </Page.BottomAppBar> <Page.Resources> <!--展开和关闭 AppBar 的动画--> <Storyboard x:Name="OpenAppBar"> <DoubleAnimation x:Name="TranslateYOpen" Storyboard.TargetName="WebView8"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Duration="00:00:00.367"> <DoubleAnimation.EasingFunction> <ExponentialEase EasingMode="EaseOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> <Storyboard x:Name="CloseAppBar"> <DoubleAnimation x:Name="TranslateYClose" Storyboard.TargetName="WebView8"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Duration="00:00:00.367"> <DoubleAnimation.EasingFunction> <ExponentialEase EasingMode="EaseOut"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </Page.Resources> <!--全屏显示的 WebView 控件--> <Grid Background="Transparent"> <WebView x:Name="WebView8"> <WebView.RenderTransform> <CompositeTransform/> </WebView.RenderTransform> </WebView> </Grid>
相应的 C# :
//在页面的构造函数中,注册 AppBar 的打开、关闭事件 public PageWithAppBar() { this.InitializeComponent(); //关联 Opened 和 Closed 事件,从而我们知道什么时候调整 WebView 控件 BottomAppBar.Opened += BottomAppBar_Opened; BottomAppBar.Closed += BottomAppBar_Closed; } protected override void OnNavigatedTo(NavigationEventArgs e) { WebView8.Navigate(new Uri("http://www.baidu.com")); } protected override void OnNavigatedFrom(NavigationEventArgs e) { BottomAppBar.Opened -= BottomAppBar_Opened; BottomAppBar.Closed -= BottomAppBar_Closed; } private void Home_Click(object sender, RoutedEventArgs e) { //单击 AppBar 上的 home 按钮后,导航到前一个页面 if (rootPage.Frame.CanGoBack) { rootPage.Frame.GoBack(); } }
显示和关闭 AppBar:
void BottomAppBar_Opened(object sender, object e) { //当 AppBar 打开时,我们需要把 WebView 控件放回到元素的 尺寸/位置。 AppBar bottomAppBar = sender as AppBar; if (bottomAppBar != null) { //强制调用 UpdateLayout() 方法,从而我们保证我们的 AppBar 的 actual height 有值 this.UpdateLayout(); // 获取 AppBar 的高度 double appBarHeight = bottomAppBar.ActualHeight; //减少 WebView 控件的高度,空间留给 Appbar WebView8.Height = WebView8.ActualHeight - appBarHeight;
// 在 Y 轴方向移动 WebView 从而回收被 AppBar 占用的空间。注意到我们只偏移 //了 AppBar 1/2 的高度,这是因为 WebView 的 VerticalAlignment 和 HorizontalAlignment 属性都设置为//'Stretch' ,所以当我们减少它的尺寸时,从 顶部和 底部个减少一半的数值 TranslateYOpen.To = -appBarHeight / 2.0;
//运行动画 OpenAppBar.Begin(); } } void BottomAppBar_Closed(object sender, object e) { AppBar bottomAppBar = sender as AppBar; if (bottomAppBar != null) { this.UpdateLayout(); double appBarHeight = bottomAppBar.ActualHeight; WebView8.Height = WebView8.ActualHeight + appBarHeight; TranslateYOpen.To = appBarHeight / 2.0; CloseAppBar.Begin(); } }