应用程序、资源和部署



本章将探讨创建和部署应用程序及其所需资源时常见的问题。

加载插件

运行 Silverlight 应用程序的最低要求是:包含用于加载 Silverlight 插件的对象标签的宿主网页,以及已编译的 Silverlight 内容本身。

如您所见,我们在对象标签中使用了 <param> 标签来指向内容。

  • HTML <Object> 标签

我们可以传递其他参数来控制一些功能,例如下载内容时显示的用户界面、发生错误时运行的 JavaScript 代码以及未安装 Silverlight 时显示的回退内容。

<Object> 在 HTML 中

这是一个加载某些 Silverlight 内容的对象标签示例。您之前已经见过这个,但我们将更详细地研究一些内容,首先是从对象标签本身的属性开始。

Type 属性

type 属性包含一个 MIME 类型,将其标识为 Silverlight 元素。这就是浏览器知道我们使用哪种嵌入式内容的方式。object 标签非常灵活。它不仅仅用于插件。您还可以使用它来托管嵌入式图像或 HTML,以及基于插件的内容,例如 Silverlight 或 Flash。

如果安装了 Silverlight 插件,则将加载它。如果没有,标准格式行为是浏览器将对象标签内的任何 HTML 内容呈现为好像对象和 param 标签不存在一样。

<object data = "data:application/x-silverlight-2," type =  "application/x-silverlight-2"  
   width = "100%" height = "100%"> 
	
   <param name = "source" value = "ClientBin/DataBinding.xap"/> 
   <param name = "onError" value = "onSilverlightError" /> 
   <param name = "background" value = "white" /> 
   <param name = "minRuntimeVersion" value = "5.0.61118.0" /> 
   <param name = "autoUpgrade" value = "true" />
	
   <a href = "http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" 
      style = "textdecoration:none"> 
		
      <img src = "http://go.microsoft.com/fwlink/?LinkId=161376" 
         alt = "Get Microsoft Silverlight" style = "border-style:none"/> 
   </a> 
	
</object>

Data 属性

下一个属性 data 就没那么明显了。末尾的逗号应该放在那里。一些重要的功能是:

  • 从技术上讲,此属性并非必需,但 Microsoft 建议您添加它,因为某些 Web 浏览器的加载插件行为相当令人意外。

  • **object 标签**旨在托管嵌入式内容,因此浏览器期望包含二进制字符串、位图文件或视频或音频流等。

  • 您通常会期望在 data 属性中放置一个 URL,浏览器下载该数据并将其传递给插件。

  • data 属性采用 URI,通常它会指向某些数据,例如 JPEG 文件,但在这里,我们使用的是稍微不同寻常的 URI 方案。

<param> 标签

我们在 object 内有各种 <param> 标签,从 source <param> 开始。

<param name = "source" value = "ClientBin/DataBinding.xap"/>

它告诉插件从哪里下载 Silverlight 内容。

您应该提供一个 JavaScript 错误处理程序。如果下载过程失败,将调用它。如果抛出未处理的异常,一旦 Silverlight 代码启动并运行,也将调用它。

<param name = "onError" value = "onSilverlightError" />

所以它不仅仅用于加载失败。您还应该指定代码所需的 Silverlight 最小版本。

Microsoft 鼓励用户保持最新状态,因此一旦机器安装了 Silverlight 插件,新版本将通过 Windows 更新提供,但用户运行的版本可能始终比您需要的版本旧。

<param name = "minRuntimeVersion" value = "5.0.61118.0" /> 
<param name = "autoUpgrade" value = "true" /> 

此 **minRuntimeVersion** 参数允许您指定所需的版本。如果安装的版本较旧,则将调用 onError 处理程序。

Silverlight 将数字错误代码传递给错误处理 JavaScript 函数,并且有一个独特的错误代码“**8001**”(碰巧如此),表示插件已过期。

您可以编写 JavaScript 代码来响应问题,或者您可以只要求插件尝试为您进行升级。

在这里,**autoUpgrade** 参数设置为“**True**”,这意味着如果安装的插件已过期,Silverlight 将自动显示一条消息,告诉用户需要较新版本,并主动提供安装。

回退 HTML 内容

在 param 标签之后,是如果未安装 Silverlight 将使用的**回退 HTML 内容**。

对于 MIME 类型未知的对象标签,标准浏览器行为是将其视为对象和 param 标签根本不存在。因此,如果没有 Silverlight 插件,将显示此标签及其内容。

<a href = "http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0"  
   style = "text-decoration:none"> 
   <img src = "http://go.microsoft.com/fwlink/?LinkId=161376"  
      alt = "Get Microsoft Silverlight" style = "border-style:none"/> 
</a>

请注意指向 **go.microsoft.com** 站点的两个 URL,一个超链接和一个图像。

图像链接解析为带有某些 Silverlight 品牌和提供安装 Silverlight 的一些文本的位图。超链接的端点相当智能。服务器检查用户代理以决定重定向位置。

它可能会返回 Silverlight 安装可执行文件,或者如果用户在不受支持的平台上,它会将浏览器定向到包含有关 Silverlight 的信息的页面。

Silverlight.js

加载 Silverlight 内容的另一种方法是替代 HTML 对象标签。Microsoft 提供了一个名为 **Silverlight.js** 的 JavaScript 文件,允许从浏览器脚本管理加载过程。

创建用于托管新创建的 Silverlight 项目的 Web 项目时,Visual Studio 会添加一个副本。Silverlight SDK 还包含此文件的副本。

**Silverlight.js** 的主要优点是它在未安装 Silverlight 时允许更大的灵活性。

XAML 资源

Silverlight 还提供了一种在 XAML 中创建**对象资源**的机制。某些类型的对象通常通过 XAML 校正,您可能希望能够在应用程序中的多个位置使用它们。在多个位置使用模板是很常见的。

如果您为按钮定义了自定义外观,您可能希望将其应用于多个按钮,甚至可能应用于应用程序中的所有按钮。XAML 资源系统提供了一种方法来实现此目的。您可以定义一个**命名资源**,然后在 XAML 中其他地方使用它。

除了模板之外,对于图形资源(例如画笔和形状)也经常需要这样做。如果您的应用程序中使用了特定的配色方案,您可以将该方案的颜色和画笔定义为资源。

这是一个用于**SolidColorBrush**资源的简单应用程序。

<UserControl x:Class = "XAMLResources.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d" 
   d:DesignHeight = "300" d:DesignWidth = "400">
   
   <UserControl.Resources> 
      <SolidColorBrush x:Key = "brushResource" Color = "AliceBlue" /> 
   </UserControl.Resources> 
	
   <Grid x:Name = "LayoutRoot" Background = "White"> 
      <StackPanel> 
         <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}" /> 
         <Rectangle Height = "50" Margin = "20" Fill = "{StaticResource brushResource}"/> 
      </StackPanel> 
   </Grid> 
	
</UserControl>

在上面的 XAML 代码中,您可以看到两个矩形都有**StaticResource** **brushResource**的颜色是**AliceBlue**。

编译并执行上述代码后,您将看到以下输出。

XAML Resources

App.xaml

所有 Silverlight 应用程序都有一个名为 **App.xaml** 的文件。它包含应用程序范围的信息。例如,它具有与用户界面元素相同的 Resources 属性。

在 **App.xaml** 文件中定义的资源可在项目中的所有 XAML 文件中使用。因此,与其使用这些类型的资源来弄乱我的 **MainPage.xaml**,我们可以将其移至应用程序范围。

<Application 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"  
   x:Class = "XAMLResources.App" > 
	
   <Application.Resources> 
      <SolidColorBrush x:Key = "brushResource" Color = "AliceBlue" /> 
   </Application.Resources>
	
</Application>

Application 类

与大多数 XAML 文件一样,**App.xaml** 文件及其对应的**代码隐藏**文件定义一个类。此 Application 类是 Silverlight 应用程序的入口点。**App.xaml** 通常处理应用程序范围的资源;其代码隐藏文件包含启动和关闭处理代码。

  • 在创建 Application 类的实例后不久,Silverlight 将引发其 **Application.Startup** 事件。

  • 在这里,我们创建用户界面。我们期望创建一个用户界面元素并将其分配给应用程序对象的 RootVisual 属性在 **Startup** 事件中,这将成为 Silverlight 插件显示的用户界面。

public partial class App : Application { 
 
   public App() { 
      this.Startup += this.Application_Startup; 
      this.Exit += this.Application_Exit; 
      this.UnhandledException += this.Application_UnhandledException;  
      InitializeComponent(); 
   }  
	
   private void Application_Startup(object sender, StartupEventArgs e) { 
      this.RootVisual = new MainPage(); 
   } 
	
   private void Application_Exit(object sender, EventArgs e) {}  
	
   private void Application_UnhandledException(object sender, 
      ApplicationUnhandledExceptionEventArgs e) { 
		
      if (!System.Diagnostics.Debugger.IsAttached) { 
         e.Handled = true; 
         Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); }); 
      } 
		
   }  
	
   private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e) { 
      try { 
         string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace; 
         errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");  
         System.Windows.Browser.HtmlPage.Window.Eval("throw new Error
            (\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); 
      } catch (Exception) {} 
   } 
} 

需要注意的事项

请注意,您无法更改 **RootVisual**。您必须只设置一次。如果您想在应用程序运行时更改用户界面,则必须通过更改 **MainPage** 的内容来实现,而不是尝试用不同的内容替换 **MainPage**。

其他应用程序事件是 **Exit**(当用户界面即将消失时,这是运行关闭代码的最后机会)和 **UnhandledException**(如果您的代码抛出未处理的异常,则会引发此事件)。

如果您未提供 **UnhandledException** 事件的处理程序,或者该处理程序未将事件标记为已处理,则 **UnhandledExceptions** 将有效地关闭您的 Silverlight 应用程序。

屏幕上的插件区域将变为空白,并将向浏览器报告脚本错误。

广告