Silverlight 4版本中加入了一系列令人兴奋的新特性,WebBrowser便是其中之一。WebBrowser是Silverlight 4版本中加入的一个运行在Silverlight应用程序内部的浏览器控件,这是一个非常有用的控件。当我们的Silverlight应用程序需要在某个位置显示一些HTML内容或是一个网页的时候,WebBrowser就会大显身手。
另一方面,通过在Silverlight应用程序嵌入WebBrowser控件的方法可以弥补Silverlight应用程序不能显示HTML网页的不足。本文中,我们将通过构建一个简化版本的Silverlight浏览器来介绍如何在Silverlight 4应用程序使用WebBrowser控件。之后,我们还要深入探讨这个控件的其他功能,力争全面了解WebBrowser控件在新一代Silverlight RIA应用程序开发下可能蕴藏的巨大能量。
在开始构建实例之前,我们还要明确:WebBrowser控件只能在浏览器外(Out-of-Browser)Silverlight应用程序中使用。
一、创建示例工程
启动Visual Studio 2010,创建一个普通的Silverlight 4应用程序,并命名为SL4WebBrowser。此后,系统会自动开启主程序界面MainPage.xaml。
现在,我们把一个WebBrowser控件拖动到上述主界面中。系统出现如下图所示的提示。
图中提示的意思是,WebBrowser控件仅能运行于浏览器外(以Out-of-Browser模式运行)。
二、修改工程属性
为了支持浏览器外运行功能,我们需要修改Silverlight应用程序的属性。为此,点击菜单“Project|SL4WebBrowser Properties…”,随后弹出如图所示的Silverlight工程属性设置对话框。
勾选图中的“Enable running application out of the browser”选项,并单击按钮“Out-of-Browser Settings…”。
注意,为了简单起见,可选择“Require elevated trust when running outside the browser”选项。这样一来,我们就能够使用WebClient类或WebBrowser控件导航到任意网址,而不必考虑Silverlight应用程序限制的跨域调用的安全问题。如果该复选框未选中,我们只能打开我们本地服务器上的网页。
三、后台代码编程
现在,我们简单地看一下后台代码中需要的编码内容:
以下是代码片段:
- public MainPage()
- {
- InitializeComponent();
- webBrowser1.Width = Application.Current.MainWindow.Width;
- webBrowser1.Height = Application.Current.MainWindow.Height;
- if (App.Current.IsRunningOutOfBrowser)
- {
- webBrowser1.Source = new Uri("http://space.itpub.net/14466241/");
- }
- }
非常简洁明了吧。下图给出了上面示例的运行时快照。
显然,上图中页面不是运行于浏览器中,而是以浏览器外方式运行的。
四、WebBrowser控件其他重要成员剖析
现在我们更深入地追踪分析WebBrowser控件提供的其他一些重要成员的使用情况。
WebBrowser控件提供了如下一些重要方法及属性,其各自的含义如下:
1. Source属性:获取或设置要显示的HTML内容对应的URI。
2. Navigate方法:要加载的HTML内容,可以是来自于一个跨域的位置。
3. NavigateToString方法:以文本方式显示要加载的HTML内容。
4. SaveToString方法:以文本方式保存在此控件中加载的HTML内容,可以是来自于一个跨域的位置。
请特别注意,出于安全原因,在使用WebBrowser控件时请务必确保与NavigateToString方法一起显示的HTML来自于受信任源。
最后,我们来观察一下WebBrowser控件的完整定义代码:
以下是代码片段:
- namespace System.Windows.Controls
- {
- public sealed class WebBrowser : FrameworkElement
- {
- // Summary:
- // Initializes a new instance of the System.Windows.Controls.WebBrowser class.
- public WebBrowser();
- // Summary:
- // Gets or sets the URI source of the HTML content to display in the System.Windows.Controls.WebBrowser
- // control.
- //
- // Returns:
- // The URI source of the HTML content to display in the System.Windows.Controls.WebBrowser
- // control.
- public Uri Source { get; set; }
- // Summary:
- // Occurs when top-level navigation completes and the content loads into the
- // System.Windows.Controls.WebBrowser control or when an error occurs during
- // loading.
- public event LoadCompletedEventHandler LoadCompleted;
- //
- // Summary:
- // Occurs when the content contained in the System.Windows.Controls.WebBrowser
- // control passes a string to the Silverlight plug-in by using JavaScript.
- public event EventHandler<NotifyEventArgs> ScriptNotify;
- // Summary:
- // Executes the specified script, which is defined in the currently loaded HTML.
- //
- // Parameters:
- // scriptName:
- // The name of the script to execute.
- //
- // Returns:
- // The result of the script invocation.
- //
- // Exceptions:
- // System.Security.SecurityException:
- // The script target is at a cross-domain location.
- public object InvokeScript(string scriptName);
- //
- // Summary:
- // Executes the specified script function, which is defined in the currently
- // loaded HTML, with the specified arguments.
- //
- // Parameters:
- // scriptName:
- // The name of the script to execute.
- //
- // args:
- // The arguments to pass to the script function.
- //
- // Returns:
- // The result of the script invocation.
- //
- // Exceptions:
- // System.Security.SecurityException:
- // The script target is at a cross-domain location.
- public object InvokeScript(string scriptName, params string[] args);
- //
- // Summary:
- // Loads the HTML content at the specified URI.
- //
- // Parameters:
- // source:
- // The URI of the HTML content to load.
- //
- // Exceptions:
- // System.Security.SecurityException:
- // The HTML content to load is from a cross-domain location.
- public void Navigate(Uri source);
- //
- // Summary:
- // Displays the specified HTML content.
- //
- // Parameters:
- // text:
- // The HTML content to display in the System.Windows.Controls.WebBrowser control.
- public void NavigateToString(string text);
- //
- // Summary:
- // Saves the source for the HTML content currently displayed in the System.Windows.Controls.WebBrowser
- // as a string.
- //
- // Returns:
- // The string representation of the source for the currently displayed HTML
- // content.
- //
- // Exceptions:
- // System.Security.SecurityException:
- // The HTML content to be saved is from a cross-domain location.
- public string SaveToString();
- }
- }
五、InvokeScript方法及ScriptNotify事件应用举例
根据前面的控件定义,我们知道:InvokeScript方法能够执行在当前加载的HTML中定义的指定脚本。
根据MSDN指示,如果对InvokeScript的调用加载跨域内容,我们可以不再用InvokeScript与该内容交互。而且,出于安全原因,你不能在
<iframe>
中承载的脚本目标上调用此方法。
InvokeScript方法提供了如下两种重载形式:
(1)public object InvokeScript(string scriptName);
(2)public object InvokeScript(string scriptName, params string[] args);
在下面的示例中,调用了InvokeScript,它在以下HTML中反过来调用LoadSearch函数。注意,这个HTML文件必须与Silverlight应用程序承载在同一个域中。
你可以使用Window.external对象的Notify方法从HTML中的JavaScript传输到托管代码。在发生此情况时,将触发ScriptNotify事件。
以下是代码片段:
- <html xmlns="http://www.w3.org/1999/xhtml" >
- <head>
- <title></title>
- <script type="text/javascript" >
- function LoadSearch(searchString) {
- window.location = "http://www.bing.com/search?q=" + searchString
- window.external.notify("Search completed")
- }
- </script>
- </head>
- <body>
- Silverlight WebBrowser control。
- </body>
- </html>
现在,让我们来观察一下客户端后台代码:
以下是代码片段:
- public partial class MainPage : UserControl
- {
- public MainPage()
- {
- InitializeComponent();
- }
- void WB1_ScriptNotify(object sender, NotifyEventArgs e)
- {
- Button1.Content = e.Value;
- Button1.IsEnabled = false;
- }
- private void Button1_Click(object sender, RoutedEventArgs e)
- {
- object results = WB1.InvokeScript("LoadSearch", new string[] { "Silverlight" });
- }
- }
接下来,让我们再来观察一下客户端Silverlight 4 XAML脚本:
以下是代码片段:
- <StackPanel x:Name="LayoutRoot" Height="358" Width="489" Background="LightBlue">
- <WebBrowser x:Name="WB1" Source="http://localhost/HTMLPage1.htm" Height="272" Width="379"
- ScriptNotify="WB1_ScriptNotify" Margin="5" />
- <Button Width="200" x:Name="Button1" Content="Click to search!" Click="Button1_Click" />
- </StackPanel>
归纳来看,InvokeScript方法及ScriptNotify事件联手提供了一种从WebBrowser控件中与其所承载的HTML中的JavaScript代码进行的一种重要途径。
六、联手使用WebBrowser和WebBrowserBrush控件
WebBrowser和WebBrowserBrush控件设计为一起使用,以便在浏览器外运行的Silverlight应用程序中显示丰富的HTML内容。
你不能旋转、应用效果或创建部分透明的WebBrowser控件。此外,不能使用WebBrowser控件覆盖HTML上的Silverlight内容。对于这些情况,应该使用WebBrowserBrush。
(一)、WebBrowserBrush简介
WebBrowserBrush是Brush对象的类型,该对象类似于VideoBrush。但是,该对象使用HTML内容而不是视频内容来绘制区域。此HTML内容由WebBrowser控件提供。与其他画笔类型类似,你可以使用WebBrowserBrush来绘制以下内容:
• 形状(例如Rectangle)的填充。
• Path的几何内容。
• Canvas的背景色。
• extBlock的前景色。
与其他类型的画笔不同,你必须通过调用Redraw方法,手动更新WebBrowserBrush中的内容。
为了使用WebBrowserBrush,你需要事先创建WebBrowser控件并且设置其Source属性。然后,你可以将WebBrowserBrush应用于要绘制的对象,并且将该WebBrowserBrush对象的SourceName属性设置为你创建的WebBrowser的名称。
如果WebBrowser中的内容有更改,你必须调用Redraw方法更新WebBrowserBrush。此外,用户无法与通过WebBrowserBrush一起显示的内容交互。下面的示例说明如何显示具有WebBrowserBrush的内容。在这个示例中,在用户移动鼠标时,将更新WebBrowserBrush的内容。
以下是代码片段:
- privatevoidLayoutRoot_MouseMove(object sender, MouseEventArgs e)
- {
- WBB1.Redraw();
- }
其中,XAML标记代码如下所示:
以下是代码片段:
- <StackPanel x:Name="LayoutRoot" Background="Blue" MouseMove="LayoutRoot_MouseMove">
- <WebBrowser Name="WB1" Source="Hello.html" Height="150" Width="150" />
- <Rectangle Height="150" Width="150" >
- <Rectangle.Fill>
- <WebBrowserBrush SourceName="WB1" Opacity=".5" x:Name="WBB1"/>
- </Rectangle.Fill>
- </Rectangle>
- </StackPanel>
通常,在你需要显示旋转、应用效果或与HTML内容交互时,一起使用WebBrowser和WebBrowserBrush控件将具有良好的效果。
(二)、WebBrowser和WebBrowserBrush联合应用例二
有时,你想在于浏览器之外运行的Silverlight应用程序中显示HTML内容。你可能想对HTML内容旋转或应用效果,但仍使用户能够与内容交互。为此,你可以将WebBrowser和WebBrowserBrush控件添加到你的应用程序以及在两者之间进行交换,具体取决于用户是否正在与内容交互。下面的代码示例演示如何使用WebBrowser和WebBrowserBrush控件。
此代码示例包含一个名为WB1的WebBrowser控件和一个名为htmlBrush的WebBrowserBrush控件。WebBrowser的源属性设置为http://www.bing.com。反过来,WebBrowserBrush的源设置为WebBrowser控件。
最初,WebBrowserBrush控件处于隐藏状态,而WebBrowser处于显示状态。当用户移动鼠标时,将隐藏WebBrowser而显示WebBrowserBrush,此时将对画笔应用转换。当用户单击HTML内容以指示他们可能想要与HTML交互时,将再次显示WebBrowser并隐藏WebBrowserBrush。
WebBrowserBrush的内容定期更新,以便它与WebBrowser控件保持同步。以下示例使用DispatcherTimer每100毫秒对WebBrowserBrush调用一次Redraw。
为了测试本示例,你需要能够在浏览器之外运行应用程序。
示例程序后台代码如下所示:
以下是代码片段:
- namespace WebBrowserBrushEx{
- public partial class MainPage : UserControl{
- DispatcherTimer dt = new DispatcherTimer();
- public MainPage(){
- InitializeComponent();
- dt.Interval = new TimeSpan(100);
- dt.Tick += new EventHandler(dt_Tick);
- }
- void dt_Tick(object sender, EventArgs e) {
- htmlBrush.Redraw();
- }
- bool animating = false;
- private void LayoutRoot_MouseMove(object sender, MouseEventArgs e) {
- dt.Start();
- if (!animating) {
- WB1.Visibility = Visibility.Collapsed;
- brush.Visibility = Visibility.Visible;
- Spin.Begin();
- animating = true;
- }
- }
- private void brush_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
- Spin.Stop();
- WB1.Visibility = Visibility.Visible;
- brush.Visibility = Visibility.Collapsed;
- animating = false;
- }
- }
- }
XAML声明性代码如下:
以下是代码片段:
- <UserControl x:Class="WebBrowserBrushEx.MainPage"
- <!--省略其他-->
- d:DesignHeight="400" d:DesignWidth="412">
- <Grid x:Name="LayoutRoot" Background="LightBlue" MouseMove="LayoutRoot_MouseMove" ShowGridLines="True">
- <Grid.RowDefinitions>
- <RowDefinition Height="40"/>
- <RowDefinition />
- </Grid.RowDefinitions>
- <Grid.Resources>
- <Storyboard x:Name="Spin" >
- <DoubleAnimation
- Storyboard.TargetName="myTransform"
- Storyboard.TargetProperty="Angle"
- From="0" To="360" Duration="0:0:5"
- RepeatBehavior="Forever" />
- </Storyboard>
- </Grid.Resources>
- <TextBlock Margin="5" Text="Right-click to install the out-of-browser application" />
- <WebBrowser Grid.Row="1" Visibility="Visible" Name="WB1" Height="350" Width="350" Source="http://www.bing.com" />
- <!—添加一个与WebBrowser控件同样大小的矩形-->
- <Rectangle Grid.Row="1" x:Name="brush" Width="350" Height="350" Visibility="Collapsed"
- MouseLeftButtonDown="brush_MouseLeftButtonDown" >
- <Rectangle.Fill>
- <!-- Fill (set background) as an HTML Brush -->
- <WebBrowserBrush x:Name="htmlBrush" SourceName="WB1"/>
- </Rectangle.Fill>
- <Rectangle.RenderTransform>
- <RotateTransform x:Name="myTransform" Angle="45" CenterX="175" CenterY="175" />
- </Rectangle.RenderTransform>
- </Rectangle>
- </Grid>
- </UserControl>
上面给出的仅仅是WebBrowser和WebBrowserBrush联合增强应用效果的基本示例,请结合上面列出的WebBrowserBrush的其他可能应用自行试验。
七、小结
WebBrowser是Silverlight 4版本中加入的一个运行在Silverlight应用程序内部的浏览器控件。当我们Silverlight应用程序需要在某个位置显示一些HTML内容或是一个网址网页的时候,借助于WebBrowser控件,实现类似功能将会得到极大简化。本文给出的仅仅是有关WebBrowser控件应用的基本示例,更复杂实用的案例需要你自己探讨开发。
原文链接:http://publish.itpub.net/a2010/0811/1089/000001089217.shtml