新浪科技

Silverlight 4 火影忍者:Web特性大显身手

IT168.com

关注

Silverlight 4版本中加入了一系列令人兴奋的新特性,WebBrowser便是其中之一。WebBrowser是Silverlight4版本中加入的一个运行在 Silverlight应用程序内部的浏览器控件,这是一个非常有用的控件。当我们的Silverlight应用程序需要在某个位置显示一些HTML内容 或是一个网页的时候,WebBrowser就会大显身手。

另一方面,通过在Silverlight应用程序嵌入WebBrowser控件的方法可以弥补Silverlight应用程序不能显示HTML网页的不足。本文中,我们将通过构建一个简化版本的Silverlight浏览器来介绍 如何在Silverlight4应用程序使用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方法的用法。

五、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的背景色。
  • TextBlock的前景色。

与其他类型的画笔不同,你必须通过调用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控件应用的基本示例, 更复杂实用的案例需要你自己探讨开发。

加载中...