Silverlight 1.0 Unleashed - 第 1 章 摘录






4.25/5 (8投票s)
2007 年 11 月 22 日
41分钟阅读

39721
Silverlight 简介,作为 Flash 的有力替代品,它允许使用轻量级的附加组件创建丰富的 Web 内容和应用程序,该附加组件对设计师和开发人员都很友好。
本章内容
- 手动嵌入 Silverlight 控件
- 让 Silverlight.js 处理繁重的工作
- 了解您的托管选项
- 以编程方式与 Silverlight 控件进行交互
尽管关于 HTML、CSS 和 JavaScript,有很多美好的东西可以谈论,但我认为大多数进行大量 Web 开发的人都会同意,它们对于开发现代网站和应用程序来说是一个相当糟糕的环境。如果您关心您的内容能在大多数 Web 浏览器(甚至只是 Internet Explorer 和 Firefox)上正常运行,适应它们的差异可能会让人抓狂。多年来,已经开发和共享了许多技术和 JavaScript 库,可以减轻这种挫败感,但它们都不是万能药。
除了浏览器差异之外,HTML 的图形功能对于人们想要创建的许多用户体验来说过于有限。使用 HTML 本身绘制简单的线条、嵌入视频以及其他许多事情都极其困难或不可能。并非这些技术设计不佳,而是它们被设计用于超链接文档,而不是如今大多数人在 Web 上想要创建的极其丰富的演示文稿。
考虑到这些问题,Adobe Flash 如此成功也就不足为奇了。无论某人是想创建一个专业设计网站、在线游戏(或其他任何应用程序),还是一个简单的广告,Flash 都是逃避 HTML 限制的自然选择。如果您怀疑 Flash 的普及程度,请尝试一下这个实验:想一种您吃的食品品牌,然后导航到该品牌的网站。很有可能您会在目的地找到 Flash 内容。(我刚试过 pepsi.com、doritos.com 和 oscarmayer.com,在撰写本文时,这三个网站都在使用 Flash。)然而,Flash 的开发体验仍有许多不足之处。Flash(运行时环境以及工具)与 HTML 面临着相同基本问题:许多人试图用它来创建丰富的应用程序,但它最初是为其他目的(在这种情况下是简单的动画)设计的。
这就是 Silverlight 的推出如此令人兴奋的原因。作为 Flash 的有力替代品,Silverlight 允许使用轻量级的附加组件创建丰富的 Web 内容和应用程序,该附加组件对设计师和开发人员都很友好。是的,Silverlight 的第一个版本在某些方面还很原始,但它是一个真正的开发平台,基于 2006 年随 Windows Presentation Foundation (WPF) 引入的概念和 API,并且在此之前已经开发了许多年。而且,与微软推出的任何软件一样,Silverlight 的下载量很小!1.0 版本小于 1.5MB,因此用户可以很快地在浏览 Silverlight 内容时获得它。(默认情况下,Silverlight 在可用时还会自动更新到更高版本。)Silverlight 可能就是许多设计师和开发人员一直在等待的万能药。
Silverlight 1.0 应用程序使用 XAML(Extensible Application Markup Language)、HTML 和 JavaScript 的混合创建,因此它们易于集成到现有 Web 内容中,并与流行的异步 JavaScript 和 XML (AJAX) 库和技术兼容。XAML 是一种基于 XML 的声明性语言,将在下一章中详细介绍。在典型的 Silverlight 应用程序中,XAML 文件包含必须在屏幕上渲染的视觉元素的层次结构。Silverlight 在初始化时解析 XAML 内容,然后相应地渲染内容。
给害怕 JavaScript 的人的一点提示
一些读者可能会对使用 JavaScript 创建 Silverlight 内容或应用程序的想法感到兴奋。然而,如果您和我认识的大多数开发人员一样,您会很失望在 1.0 版本中“被迫”使用它。不过,用 JavaScript 编程并非世界末日。JavaScript 是一种非常强大的动态语言,如果您遵循人们多年来设计的巧妙模式,您甚至可以用面向对象的方式使用它。(请注意,JavaScript 与 Java 没有任何关系。)
此外,现在异步 JavaScript 和 XML (AJAX) 正如火如荼,有许多有用的工具和库可以帮助您高效地使用 JavaScript,而且它们还在不断改进。Visual Studio 2008 在 JavaScript 开发方面进行了许多改进,特别是与调试和 IntelliSense 相关的方面。
在 JavaScript(用作网站的一部分时)中编程的痛苦通常不是因为语言本身,而是因为各种 Web 浏览器提供的 HTML 文档对象模型 (DOM) 之间的差异。幸运的是,仅与 Silverlight 对象交互的 JavaScript 编写没有这个问题,因为 Silverlight 对象模型无论主机浏览器如何都保持不变。大多数 Silverlight 应用程序仍然需要与 HTML DOM 交互的 JavaScript,但您接触 DOM 的机会可以大大减少。对于这些情况,ASP.NET AJAX(或其他流行的 AJAX 库)是隐藏浏览器差异的绝佳选择。
如果您仍然不相信,请放心,下一版本的 Silverlight(已提供预发行版本)支持使用 C#、Visual Basic、IronRuby、IronPython 和其他 .NET 语言编写的过程代码。对于那些热爱 JavaScript 的人来说,下一版本的 Silverlight 应该支持编译(基于 .NET)的 JavaScript,其性能比今天浏览器中运行的解释型 JavaScript 快几个数量级。其中一些语言将成为核心 Silverlight 下载的一部分,而其他语言可能需要额外的按需下载。
Silverlight 和 Adobe Flash 有什么区别?
“Flash”是运行时组件和设计工具的名称。“Silverlight”仅指运行时组件,但有用于 Silverlight 的设计工具(如 Expression Blend)和开发工具(如 Visual Studio)。
多年来,Flash 一直是富 Web 内容的唯一可行选择,现在 Silverlight 定位为满足相同的需求。这两种技术具有相似的功能,但各有优缺点。
Flash(运行时组件)最大的优势在于其普及性。网站可以使用 Flash,并且可以确信绝大多数用户已经安装了必要的播放器。另一方面,Silverlight 是全新的,需要一些时间来普及——这取决于网上引人注目的 Silverlight 内容的数量。当然,Flash 和 Silverlight 的安装都设计得快速而无痛,因此如果用户没有必要的软件,网站不必让用户感到太不便。但即使 Silverlight 在最初几个月像野火一样蔓延,Flash 运行时组件仍然可以到达 Silverlight(尚)不能到达的地方,例如移动设备。
Flash 具有 Silverlight 所缺乏的各种视觉功能,例如位图效果(模糊和发光)以及形状补间(在动画中使对象的形状变形)。Silverlight 值得注意的、Flash 所不具备的功能包括更高质量的视频(即使是带有 VC-1 编解码器的 HD 720p 全屏,只要硬件合适)、与 HTML 的无缝交互、支持来自触控笔或触摸设备的が(高分辨率和压力敏感输入数据,以及内容比使用编译脚本而不是 XML 更易被搜索引擎发现。
Silverlight 相对于 Flash 的最大优势在于平台及其相关工具的设计。如果您要构建一个交互式应用程序而不是简单的内容,这个优势就尤其明显。Flash(设计工具)在创建即使只有少量逻辑的应用程序时,学习曲线非常陡峭,而且生成的代码通常非常不自然(且难以调试)。但是,大多数软件开发人员,甚至那些涉猎 HTML 和少量编程的人,都会发现 Silverlight 的学习曲线相当小。而且,如果您碰巧已经熟悉 WPF,学习 Silverlight 将会是轻而易举的事。
Silverlight 和 WPF 有什么区别?
Silverlight 被设计用于创建可以在多个浏览器和多个操作系统中查看的富 Web 内容或应用程序,而 WPF 被设计用于创建富 Windows 应用程序。WPF 应用程序需要 .NET Framework 3.0 或更高版本,这比 Silverlight 的下载量要大得多,尽管 Windows Vista 及更高版本的操作系统已经默认安装了它。
Silverlight 1.0 essentially is a subset of WPF, although Silverlight also has a few unique pieces related to video, on-demand downloading of any content, and the control that hosts the content inside a web page. Some WPF features missing from Silverlight 1.0 are common user interface controls (such as buttons and scrollbars), layout panels, 3D graphics, data binding, rich document support, performance optimizations from hardware accelerated graphics, and more. In addition, Silverlight 1.0 applications don't have the benefit of the depth and breadth of the .NET Framework APIs, unless you use them from server-side ASP.NET code. The next version of Silverlight will close some of the gap between Silverlight and WPF, but it will undoubtedly always remain a subset of what WPF and the full .NET Framework provide.
虽然 Silverlight 1.0 的编码是用 JavaScript 完成的,这与 WPF(以及未来版本的 Silverlight)使用的 .NET 语言大相径庭,但这两种技术高度兼容。在某些情况下,与用户界面相关的 Silverlight 代码——特别是 XAML 内容——可以很少修改地在 WPF 应用程序中重用,反之亦然。选择 Silverlight 和 WPF 的关键在于您是想优化覆盖范围还是富功能。这实际上与选择 Web 应用程序还是 Windows(或其他 OS)应用程序的经典选择没有区别。除了前面提到的 3D 图形等功能外,如果您需要离线支持或广泛的本地存储,WPF 应用程序是自然的选择。
WPF 不仅支持 Windows 应用程序,还支持在浏览器中运行的称为 XAML 浏览器应用程序(XBAP)的应用程序。XBAP 毫无疑问可以被认为是 Web 应用程序,因为它们的内容在浏览器中无缝渲染,类似于 Silverlight 内容。然而,XBAP 需要 .NET Framework 3.0 或更高版本,因此它们只能在 Windows 上运行(并且仅当安装了 .NET Framework 时),并且仅在 Internet Explorer 和 Firefox 中工作。(此外,Firefox 支持需要 .NET Framework 3.5 或更高版本。)XBAP 支持比 Silverlight 1.0 更大的 WPF 功能子集,因此它们可以成为创建富 Web 样式的应用程序的合适选择。例如,大英图书馆有一个名为“翻页”的应用程序(此处),该应用程序在浏览器中使用 WPF 3D 图形。
Silverlight 1.0 与 Silverlight 预发行版本之间有什么关系?
Silverlight 的下一个版本(当前标记为 1.1)在 Silverlight 1.0 完成之前就已经提供预发行版本,这有点不寻常,但正如版本号所示,它仅仅是 Silverlight 的下一个版本。这个下一个版本是 Silverlight 1.0 的超集,并且仍然是 WPF 和 .NET Framework 的子集(但它也有一些独特的功能)。下一个 Silverlight 版本计划添加的最重要的功能是
-
.NET 支持,这意味着不仅支持更多语言,还包括 .NET Framework 的基类库子集
-
WPF 中已有的几个功能:用户界面控件、布局、数据绑定等
-
对其他浏览器和操作系统(如 Windows 2000)的潜在支持
尽管如此,您学到的所有关于 Silverlight 1.0 的知识都直接适用于未来版本的 Silverlight。
需要什么 Web 服务器来提供 Silverlight 内容?
任何 Web 服务器都可以,但请确保为 .xaml 文件设置 MIME 类型。使用 Windows Server 在流媒体方面可以提供额外的优势,例如 Windows Media Services 中的 Faststream 技术。Windows Live 的 Silverlight 流媒体(参见此处)也可以成为在他人 Web 服务器上托管 Silverlight 内容的有吸引力的选择。它支持免费(如果您不介意广告与您的内容一起提供)或付费的可扩展流媒体。
Windows 版 Silverlight、Mac OS X 版 Silverlight 和 Linux 版 Silverlight 有什么区别?
Silverlight 支持相同的功能集,因为它旨在在所有支持的操作系统和浏览器之间完全兼容。Silverlight 在 Windows 上的一项优势是能够从触控笔或触摸设备获取高分辨率和压力敏感的输入数据,尽管这些额外信息以避免编写特定于 Windows 的代码的方式提供。(有关更多详细信息,请参阅第 7 章“响应输入事件”。)Silverlight 在不同浏览器和操作系统上的性能特征也不同。例如,无窗口控件(本章稍后介绍)和具有透明度的元素在 Mac OS X 的 Safari 中尤其慢。当然,Silverlight 存在仅适用于特定浏览器或操作系统的 bug。本书中指出了其中一些。
手动嵌入 Silverlight 控件
Silverlight,就像 Adobe Flash 一样,是一种 Web 浏览器附加组件。它是一对组件——一个用于 Internet Explorer(ActiveX 控件),另一个用于所有其他支持的浏览器(Netscape 插件)——但这只是一个不可见的实现细节,以确保“即插即用”,无论主机浏览器如何。Web 页面利用附加组件的标准方式——无论是 Silverlight、Flash 还是其他——是使用 OBJECT
HTML 元素。
列表 1.1 包含一个简单的网页,用于一个虚构的“Great Estates”房产开发项目,该项目使用 OBJECT
元素在顶部嵌入了一个 Silverlight logo。
列表 1.1 带有嵌入式 Silverlight 内容的网页
<html>
<head>
<title>Great Estates</title>
</head>
<body style="background:blue">
<!— A Silverlight-based logo: —>
<object type="application/x-silverlight" id="silverlightControl"
width="390" height="100">
<param name="background" value="Yellow"/>
<param name="source" value="Chapter1.xaml"/>
</object>
<p style="font-family:Tahoma; color:white">
An idyllic new community located high on a hill and offering captivating
waterfront views. Tailored to meet both the needs of upsizing and
downsizing buyers, Great Estates offers custom quality architecture and
design at an affordable price point.
</p>
</body>
</html>
OBJECT
元素上的 id
、width
和 height
属性的工作方式与 DIV
、TABLE
等元素相同。例如,width
和 height
可以以绝对像素值或百分比指定。type
属性指的是附加组件内容的 MIME 类型。当内容类型为 application/x-silverlight
时,主机浏览器会调用 Silverlight 附加组件。
Silverlight 附加组件支持几个自定义参数,将在后面的“了解您的托管选项”部分介绍。在此示例中,background
参数设置为用黄色填充 390x100 的区域,而 source
参数指向一个单独的 XAML 文件,其中包含要在黄色背景上渲染的内容。此 XAML 文件 Chapter1.xaml 显示在列表 1.2 中。
列表 1.2 Chapter1.xaml — 包含 Logo 的 XAML 文件
<Canvas xmlns="http://schemas.microsoft.com/client/2007">
<MediaElement Name="video" Source="Lake.wmv" Opacity="0" IsMuted="true"/>
<!-- A circle containing a live video: -->
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<VideoBrush SourceName="video"/>
</Ellipse.Fill>
</Ellipse>
<!-- Two pieces of text: -->
<TextBlock FontFamily="Georgia" Foreground="Blue" FontStyle="Italic"
FontSize="40" Canvas.Left="125" Canvas.Top="20" Text="Great Estates"/>
<TextBlock Foreground="Blue" Canvas.Left="110" Canvas.Top="70"
Text="Luxurious Living at an Affordable Price"/>
<!-- Curves and a line: -->
<Path Stroke="Red" StrokeThickness="4">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,65">
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="25,65"/>
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="50,65"/>
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="75,65"/>
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="100,65"/>
<LineSegment Point="390,65"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
此 XAML 文件定义了一个包含两行文本、一些矢量艺术品,甚至还有一个被裁剪成圆形的实时视频的 logo!现在不要担心 XAML 文件的语法。下一章将介绍您需要了解的关于 XAML 语法的所有知识,而各种 Silverlight 元素(Canvas
、MediaElement
、Ellipse
等)将在本书的其余部分中介绍。
图 1.1 显示了由列表 1.1 和 1.2 定义的网页。大多数网页可能会通过为 OBJECT
元素提供匹配的背景来更好地融合 Silverlight 内容,但在此示例中,黄色背景有助于突出 Silverlight 渲染的页面区域。

Silverlight 内容手动托管在带有
OBJECT
元素的网页中。
HTML 和 CSS 字体、颜色等不会被 Silverlight 内容继承!
Silverlight 内容的字体、颜色和其他视觉方面完全独立于页面上的任何其他设置。如果您想为 Silverlight 内容应用不同的主题,您将需要采用自定义机制来实现。
当然,只有在查看器安装了 Silverlight 附加组件的情况下,Great Estates 网页才与图 1.1 中显示的内容类似。没有附加组件,页面看起来类似于图 1.2(具体取决于您使用的浏览器)。

当 Silverlight 附加组件缺失或禁用时,列表 1.1 的显示效果不佳。
幸运的是,对于那些没有附加组件的用户来说,有一个相对简单的解决方案可以提供良好的体验。如果您将内容直接放在 OBJECT
元素内,浏览器将在出现故障时呈现该内容。因此,列表 1.1 中的 OBJECT
元素可以更新如下,以便将 Logo 降级为简单的图像,供没有 Silverlight 的查看者使用
<object type="application/x-silverlight" id="silverlightControl"
width="390" height="100">
<param name="background" value="Yellow"/>
<param name="source" value="Chapter1.xaml"/>
<!-- Alternative content: -->
<img src="logo.png"/>
</object>
logo.png 中的 Logo 可能看起来与图 1.1 中显示的 Silverlight Logo 相同,只是实时视频变成了静态图像。如果您不想创建降级版本的 Silverlight 内容,您可以随时通知用户并帮助他们安装 Silverlight 附加组件。
<object type="application/x-silverlight" id="silverlightControl"
width="390" height="100">
<param name="background" value="Yellow"/>
<param name="source" value="Chapter1.xaml"/>
<!-- Alternative content: -->
This content requires Silverlight. <a href=
"http://www.microsoft.com/silverlight/downloads.aspx">Get it here.</a>
</object>
不幸的是,Apple 的 Safari 浏览器目前不支持 OBJECT
元素。取而代之的是,您必须使用一个名为 EMBED
的元素,该元素碰巧在 Internet Explorer 和 Firefox 中也有效。列表 1.3 包含对列表 1.1 的此更新,以便也能在 Safari 上运行。
列表 1.3 使用 EMBED 而不是 OBJECT 嵌入 Silverlight 内容
<html>
<head>
<title>Great Estates</title>
</head>
<body style="background:blue">
<!-- A Silverlight-based logo: -->
<embed type="application/x-silverlight" id="silverlightControl"
width="390" height="100" background="Yellow" source="Chapter1.xaml"/>
<p style="font-family:Tahoma; color:white">
An idyllic new community located high on a hill and offering captivating
waterfront views. Tailored to meet both the needs of upsizing and
downsizing buyers, Great Estates offers custom quality architecture and
design at an affordable price point.
</p>
</body>
</html>
除了不同的元素名称(EMBED
而不是 OBJECT
)之外,唯一的区别是自定义参数被指定为 EMBED
元素的属性,而不是作为子元素。替代内容(在嵌入失败时使用)可以通过单独的 NOEMBED
元素指定。使用 EMBED
的结果与图 1.1(至少是 Silverlight 内容)相同,如图 1.3 所示。

在 Mac OS X 上的 Apple Safari 浏览器中查看的、使用
EMBED
元素手动托管在网页中的 Silverlight 内容。
使用 EMBED
是在所有支持的浏览器中呈现内容的简单方法,尽管对于 Internet Explorer 和 Firefox 来说,OBJECT
是首选。
让 Silverlight.js 处理繁重的工作
手动使用 OBJECT
或 EMBED
元素嵌入 Silverlight 内容存在许多问题。存在对浏览器差异的担忧(尽管通过始终坚持使用 EMBED
可以避免)。最重要的是,正确处理 Silverlight 检测将是一项相当大的工作。例如,虽然在 OBJECT
元素内放置下载链接作为替代内容(或使用 NOEMBED
元素)似乎足够简单,但如果有人安装了错误版本的 Silverlight,它就不会正常工作。如果一个网页包含使用 1.0 中不可用的未来功能的 Silverlight 内容,安装了 1.0 的查看者将看不到替代内容。相反,Silverlight 1.0 附加组件将尝试渲染内容并失败。
如果微软要求每个人自己进行适当的版本检测工作,那将是一个巨大的错误。涉及的代码并不简单,并且任何软件的版本检测逻辑都以错误地完成而闻名。(听起来很傻,但有人可能会编写适用于版本号 1.0 和 1.1 的逻辑,但在几年后版本 4.0 出现时却会失败。)果然,Silverlight 软件开发工具包 (Silverlight SDK) 提供了一个名为 Silverlight.js 的 JavaScript 文件,该文件定义了一个简单的 JavaScript 函数,可以处理从将适当的 OBJECT
或 EMBED
元素注入 HTML 文档到检查是否安装了正确版本的 Silverlight,然后将查看者引导到安装它的适当位置(如果未安装)。除非您的内容必须出现在不允许 JavaScript 的环境中,否则您应该始终使用 Silverlight.js(本节讨论)中的功能,而不是直接使用 OBJECT
或 EMBED
。
Silverlight.createObject
Silverlight.js 中公开的简单函数是 Silverlight.createObject
。这是在 JavaScript 中调用 createObject
的方法,以生成如列表 1.1 和 1.3 所示的 OBJECT
/EMBED
元素
Silverlight.createObject(
"Chapter1.xaml", // source XAML
document.getElementById("placeholder"), // parent HTML element
"silverlightControl", // id for the control
// properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow" },
// events:
{}
);
第一个参数成为动态生成的 OBJECT
或 EMBED
元素的 source
值,第三个参数成为它的 id
。第二个参数可以是一个现有的 HTML 元素,用于包含新的 OBJECT
或 EMBED
元素。在此示例中,使用标准的 document.getElementById
函数通过 HTML id
(placeholder
)从页面检索元素,但您也可以传递 document.body
,如果您想直接将新元素附加到页面的 body。
提示 — 如果将父 HTML 元素传递为 null
,createObject
将返回一个包含 OBJECT
或 EMBED
元素的字符串,这些元素本应被添加到父元素中。这为您提供了在页面上添加元素时的灵活性,以便对其进行修改或以其他方式自定义。
createObject
的第四个和第五个参数分别是 Silverlight 附加组件支持的属性和事件的关联数组。属性数组是值的组合,这些值要么更改 Silverlight.js 中的逻辑(例如 version
),要么直接应用于 OBJECT
或 EMBED
元素(例如 width
和 height
),要么在 OBJECT
元素使用时作为 PARAM
元素子项应用(例如 background
)。即将到来的“了解您的托管选项”部分将介绍各种属性(和事件)。这里显示唯一的新属性是 version
,它应该简单地设置为您目标 Silverlight 的版本(1.0)。
提示 — createObject
函数有第六个和第七个(可选)参数,这两个参数都可以用于将自定义数据附加到 Silverlight 控件。例如,如果将第六个参数(initParams
)设置为字符串“custom”,动态生成的 OBJECT
元素将具有以下额外子项
<param name="initParams" value="custom"/>
有了这个,您就可以编写 JavaScript,使用标准的 DOM 函数遍历 HTML 元素树,或者使用本章末尾介绍的一个简单的 Silverlight 特定属性 InitParams
来检索此值。如果您将第七个参数(context
)设置为任何对象,该对象将被作为参数传递给控件的 onLoad
事件处理程序(本章后面将介绍)。此 context
功能特定于 Silverlight.js,并且与 initParams
不同,无法通过 HTML 中的 PARAM
元素实现。
这些机制提供的功能仅仅是 JavaScript 文件之间通信的额外方式,这些文件可能作为独立组件进行开发。
Silverlight.createObjectEx
Silverlight.js 定义了第二个用于嵌入 Silverlight 内容的函数,名为 Silverlight.createObjectEx
。(Ex
后缀是旧的 Win32 约定,它神秘地出现在了这个文件中。它通常表示一个函数的新版本或“额外”版本。)createObject
和 createObjectEx
之间的唯一区别是后者接受一个包含所有相同信息的单个关联数组参数。例如,以下是对 createObject
的先前调用,将其转换为对 createObjectEx
的调用
Silverlight.createObjectEx(
// Just one parameter, an array with 5 elements:
{
source: "Chapter1.xaml",
parentElement: document.getElementById("placeholder"),
id: "silverlightControl",
properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow" },
events: {}
}
);
createObjectEx
的优点是调用具有自描述性。您可以清楚地看到哪个数据是 source
、parentElement
等,而无需注释。因此,本书中的示例使用 createObjectEx
而不是 createObject
。调用 createObjectEx
的语法可能看起来不寻常,但它基本上是 JSON(JavaScript Object Notation),一种基于简单 JavaScript 结构流行的数据交换格式。
createObjectEx 的实现
createObjectEx
是 createObject
的一个非常简单的包装器,正如您从 Silverlight.js 中的源代码中可以看出。它的实现如下
Silverlight.createObjectEx = function(params)
{
return Silverlight.createObject(params.source, params.parentElement,
params.id, params.properties, params.events, params.initParams,
params.context);
}
在 JavaScript 中,像 a.b
这样的语法等同于 a["b"]
,这就是为什么 params.source
可以用来访问 params
数组的 source
元素,等等。
整合
createObject
或 createObjectEx
函数可以从任何 JavaScript 文件或内联 SCRIPT
元素调用,但微软发布了以下推荐的用法:
- 创建一个名为 CreateSilverlight.js 的单独脚本文件(按惯例)
- 在 CreateSilverlight.js 中定义一个无参数函数(按惯例命名为
createSilverlight
),该函数调用createObject
或createObjectEx
。 - 从 HTML 文档中的
SCRIPT
元素(通常在文档的HEAD
中)引用 Silverlight.js 和 CreateSilverlight.js。 - 在文档中放置一个要包含 Silverlight 内容的 HTML 元素,例如
DIV
,并为其指定一个id
(由您的createSilverlight
函数使用)。 - 在 HTML 文档的内联 JavaScript 中调用无参数函数。
调用 createObject 或 createObjectEx 时,某些属性和事件不可省略! — 如果省略 version
属性,您将收到脚本错误;如果省略 width
或 height
,则生成的元素将不可见。至于 events
,您至少必须指定一个空的关联数组({}
);否则,您将收到脚本错误。
列表 1.4 和 1.5 遵循此方法,以获得与图 1.1 和图 1.3 中看到的相同结果。
列表 1.4 使用推荐的 Silverlight.js 方法嵌入 Silverlight 内容
<html>
<head>
<title>Great Estates</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="CreateSilverlight.js"></script>
</head>
<body style="background:blue">
<!-- A Silverlight-based logo: -->
<div id="placeholder">
<script type="text/javascript">createSilverlight();</script>
</div>
<p style="font-family:Tahoma; color:white">
An idyllic new community located high on a hill and offering captivating
waterfront views. Tailored to meet both the needs of upsizing and
downsizing buyers, Great Estates offers custom quality architecture and
design at an affordable price point.
</p>
</body>
</html>
列表 1.5 CreateSilverlight.js — 带有无参数 createSilverlight 函数的推荐脚本文件
function createSilverlight()
{
Silverlight.createObjectEx(
{
source: "Chapter1.xaml",
parentElement: document.getElementById("placeholder"),
id: "silverlightControl",
properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow" },
events: {}
}
);
}
避免 Internet Explorer 中的“单击以激活并使用此控件” — 取决于 ActiveX 控件的使用方式,当前版本的 Internet Explorer 要求查看者通过单击它(或在获得焦点时按 Enter 键或空格键)来“激活”网页。激活后,控件即可接受键盘和鼠标输入。将鼠标悬停在这些控件上会显示边框和工具提示,如图 1.4 所示。

Internet Explorer 中烦人的“单击以激活并使用此控件”行为。
这种行为无疑很烦人,但对于应该与 HTML 无缝融合的内容来说尤其如此。对于这个例子,为什么页面查看者会关心激活一个 Logo 呢?这个反功能的存在是因为最近了结的一项专利诉讼(Eolas v. Microsoft),该诉讼要求微软更改 Internet Explorer 处理 ActiveX 控件的方式。
幸运的是,有一些技术可以避免激活行为,如各种文章(例如这篇)中所述。更好的是,通过遵循使用 Silverlight.js 和 CreateSilverlight.js 的推荐方法,您无需做任何额外的工作。这就是为什么查看列表 1.1 和 1.3 中的页面会显示“单击以激活并使用此控件”提示,而列表 1.4 中的页面(以及本书中其余的示例)则不会。
Silverlight Streaming by Windows Live
Silverlight Streaming by Windows Live 是一项 Web 服务,可免费(含广告)或付费提供高度可扩展的 Silverlight 内容托管和流式传输。该服务有自己的一套打包和上传内容的程序,但内容的消耗与常规 Silverlight.js 方法非常相似。您无需引用自己的 Silverlight.js 副本,而是可以引用 Silverlight Streaming 提供的修改后的 Silverlight.js。然后,您可以调用 Silverlight.createHostedObjectEx
——此服务定义的特殊函数——该函数会将一个 IFRAME
嵌入到您的 HTML 文档中,而不是直接嵌入 OBJECT
或 EMBED
元素。传递给 createHostedObjectEx
的 source
必须是一个特殊字符串,其中包含您之前必须在 Silverlight Streaming 服务中注册的信息。或者,您可以通过将 IFRAME
的源设置为特定于您的托管应用程序的特殊 URL 来利用 Silverlight Streaming,而无需 JavaScript。有关更多详细信息,请访问Silverlight Streaming 页面。
了解您的托管选项
Silverlight 公开了许多属性和事件,用于自定义 Silverlight 内容的外观以及它与其中包含的 HTML 文档的交互方式。此外,Silverlight 附加组件提供的 source
参数支持比之前描述的功能更多的功能。本节将探讨 source
的额外功能,然后介绍附加组件直接公开的所有属性和事件。
source
先前的列表演示了 source
的最常见用法,将其设置为 Web 服务器上 XAML 文件的名称(以及路径,如果适用)。但是,您也可以将 XAML 内联放置在 HTML 文档中。这需要两个步骤:
- 将 XAML 内容放在类型为
text/xaml
的SCRIPT
元素中,位于将包含 Silverlight 控件的 HTML 元素之前,并为其指定一个唯一的id
。 - 使用
SCRIPT
元素的id
,前面加上#
,作为传递给 Silverlight 附加组件的source
值。#
前缀是区分id
和文件名的地方。
列表 1.6 和 1.7 是对列表 1.4 和 1.5 的更新,它们消除了对单独的 Chapter1.xaml
文件的依赖。
列表 1.6 将内联 XAML 放在 HTML 中
<html>
<head>
<title>Great Estates</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="CreateSilverlight.js"></script>
</head>
<body style="background:blue">
<!-- A Silverlight-based logo: -->
<script id="xaml" type="text/xaml">
<Canvas xmlns="http://schemas.microsoft.com/client/2007">
<MediaElement Name="video" Source="Lake.wmv" Opacity="0" IsMuted="true"/>
<!-- A circle containing a live video: -->
<Ellipse Width="100" Height="100">
<Ellipse.Fill>
<VideoBrush SourceName="video"/>
</Ellipse.Fill>
</Ellipse>
<!-- Two pieces of text: -->
<TextBlock FontFamily="Georgia" Foreground="Blue" FontStyle="Italic"
FontSize="40" Canvas.Left="125" Canvas.Top="20" Text="Great Estates"/>
<TextBlock Foreground="Blue" Canvas.Left="110" Canvas.Top="70"
Text="Luxurious Living at an Affordable Price"/>
<!-- Curves and a line: -->
<Path Stroke="Red" StrokeThickness="4">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,65">
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="25,65"/>
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="50,65"/>
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="75,65"/>
<ArcSegment SweepDirection="Clockwise" Size="2,2" Point="100,65"/>
<LineSegment Point="390,65"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
</script>
<div id="placeholder">
<script type="text/javascript">createSilverlight();</script>
</div>
<p style="font-family:Tahoma; color:white">
An idyllic new community located high on a hill and offering captivating
waterfront views. Tailored to meet both the needs of upsizing and
downsizing buyers, Great Estates offers custom quality architecture and
design at an affordable price point.
</p>
</body>
</html>
列表 1.7 CreateSilverlight.js — 使用内联 XAML 作为源
function createSilverlight()
{
Silverlight.createObjectEx(
{
source: "#xaml",[strong]
parentElement: document.getElementById("placeholder"),
id: "silverlightControl",
properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow" },
events: {}
}
);
}
此 #id
语法支持 source
可能被指定的任何地方:createObject
、createObjectEx
、直接在 EMBED
元素上,或作为 OBJECT
元素内的 PARAM
。这种功能是将通常需要两次 Web 请求合并为一个的便捷方法。但除了效率考虑之外,移除对自定义外部文件的依赖使服务器端代码(例如 ASP.NET 或 PHP)能够完全封装地发出 Silverlight 内容。
属性
Silverlight 暴露的 width
、height
和 version
属性很直接,但 background
属性需要稍作解释。此外,Silverlight 附加组件还支持一些尚未讨论过的属性。
内联 XAML 在 Firefox 中不起作用,除非移除了 DOCTYPE 元素!
在 HTML 页面中放置一个 DOCTYPE
(文档类型声明)来指定您正在使用哪个版本的 HTML 或 XHTML 是一种最佳实践。然而,当前版本的 Firefox 有一个 bug,它会阻止内联 XAML 在带有 DOCTYPE
的页面上工作。因此,如果您希望您的内容在 Firefox 上呈现,您必须选择仅使用其中之一。
用作源的 XAML 文件必须与 Web 页面来自同一域!
您不能将 Silverlight 控件的 source
设置为与托管 HTML 文档的域(或协议)不同的域(或协议)。此限制是故意的,作为一种安全措施。虽然此限制不必要地严格(在此作者看来),但它至少与浏览器强制执行其 XmlHttpRequest
对象所遵循的策略一致,称为同源策略。(人们认为来自不同域的 XML 比来自不同域的 JavaScript 更危险,因为所有浏览器都阻止前者但允许后者!我不会惊讶地看到浏览器在未来几年内改变它们的策略。)
background
background
属性——可以通过 createObject
、createObjectEx
或直接在 OBJECT
/EMBED
元素上设置——比普通的 HTML 颜色值更强大。除了命名颜色(如 Red
或 Yellow
)和 RGB 值(如 #F1F1F1
或 #456
)之外,background
还可以设置 alpha 通道以创建透明或半透明的背景颜色。语法是 #AARRGGBB
(或 #ARGB
),因此半透明的红色将是 #77FF0000
(或 #7F00
)。background
还可以设置为命名值 Transparent
,这与 alpha 通道值为零的任何颜色相同。如果完全省略 background
,控件将获得白色背景。
isWindowless
默认情况下,Silverlight 控件的实例被称为窗口化,但通过将 isWindowless
设置为 true
(可以通过 createObject
、createObjectEx
或直接在 OBJECT
/EMBED
元素上完成),您可以将其更改为“无窗口”控件。窗口化与无窗口的区别并非 Silverlight 特有,而是指 Windows 上的低级实现细节(控件是否有自己的窗口句柄,或 HWND
)。
提示 - 除了使用文字字符串外,您还可以将 background
设置为任何现有 HTML 元素的颜色。例如,以下调用使 Silverlight 控件的背景颜色与主机文档的背景颜色匹配,前提是它已通过 style
属性设置了背景颜色
Silverlight.createObjectEx
{
...
properties:
{ ... , background: document.body.style.backgroundColor },
...
);
这比使用 Transparent
的背景颜色要好得多,因为它适用于所有其他 Silverlight 属性设置,并且可以提供显著更好的性能。
重要的是要理解无窗口控件的两种不同行为:
- 无窗口控件尊重 HTML 的 z-indexing,因此您可以将 HTML 内容叠加和重叠在 Silverlight 之上,反之亦然。而窗口化控件始终渲染在最上面。
- 无窗口控件支持透明度,因此可以设置透明或半透明的背景,并且其中的内容可以是透明或半透明的。
只有当 isWindowless 设置为 true 时,透明或半透明的背景颜色才能按预期工作! — 如果不将其设置为 true
,设置为 Transparent
的 background
将显示为黑色,半透明颜色将与黑色混合,而不是与 Silverlight 控件后面的 HTML 内容混合。
使用无窗口控件或透明/半透明背景可能会严重影响性能! — 无窗口控件和具有 alpha 通道的颜色会产生性能问题,尤其是在 Mac OS X 的 Safari 中。因此,除非无窗口控件和透明/半透明内容所启用的行为是绝对必要的,否则您应该避免使用这些功能。
图 1.5 显示了 Great Estates 网站可能利用无窗口 Silverlight 内容的一种方式——将 HTML SELECT
元素放置在 Silverlight logo 之上。

无窗口 Silverlight 控件允许 HTML 出现在其之上。
为了创建图 1.5 中的结果,列表 1.8 将一个 SELECT
元素添加到列表 1.4 的页面中,并使用 CSS 为其设置绝对定位和 z-index,以确保它放置在 Silverlight 内容之上。
列表 1.8 将 HTML SELECT 元素放置在 Silverlight 控件前面
<html>
<head>
<title>Great Estates</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="CreateSilverlight.js"></script>
</head>
<body style="background:blue">
<!-- A Silverlight-based logo: -->
<div id="placeholder">
<script type="text/javascript">createSilverlight();</script>
</div>
<select style="position:absolute; left:289px; top:18px; z-index:1">
<option>California</option>
<option>Pennsylvania</option>
<option>Washington</option>
</select>
<p style="font-family:Tahoma; color:white">
An idyllic new community located high on a hill and offering captivating
waterfront views. Tailored to meet both the needs of upsizing and
downsizing buyers, Great Estates offers custom quality architecture and
design at an affordable price point.
</p>
</body>
</html>
列表 1.8 仅产生所需结果是因为相应的 CreateSilverlight.js 文件将 isWindowless
设置为 true
,如列表 1.9 所示。
列表 1.9 CreateSilverlight.js — 在无窗口控件中托管熟悉的 Silverlight 内容
function createSilverlight()
{
Silverlight.createObjectEx(
{
source: "Chapter1.xaml",
parentElement: document.getElementById("placeholder"),
id: "silverlightControl",
properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow",
isWindowless: "true" },
events: {}
}
);
}
isWindowless 的布尔值必须指定为字符串! — 以下属性设置在调用 createObject
或 createObjectEx
时有效
{ ... , isWindowless: "true", ... }
但以下设置无效:
{ ... , isWindowless: true, ... }
任何非字符串都被视为 false
,因此无效!
inplaceInstallPrompt
inplaceInstallPrompt
属性(只能与 createObject
或 createObjectEx
一起使用)控制当查看者没有适当版本的 Silverlight 时显示的 Silverlight 安装图形的外观和行为。图 1.6 显示了两个选项的外观。将 inplaceInstallPrompt
设置为 false
(默认行为)会显示一个小图形,链接到官方下载页面以获取更多信息。设置为 true
会显示额外文本,但链接现在直接指向要下载的文件,而不是一个中间页面。

Silverlight.js 支持的两种不同的安装提示。
inplaceInstallPrompt 的布尔值不能指定为字符串! — 与 isWindowless
的情况不同,以下属性设置在调用 createObject
或 createObjectEx
时有效
{ ... , inplaceInstallPrompt: false, ... }
但以下设置无效:
{ ... , inplaceInstallPrompt: "false", ... }
任何字符串都被视为 true
!
maxFramerate
maxFramerate
参数可以通过 createObject
、createObjectEx
或直接在 OBJECT
/EMBED
元素上设置,它自定义 Silverlight 控件渲染内容的最高帧速率,以每秒帧数计。(实际帧速率取决于客户端计算机及其当前负载。)maxFramerate
的默认值为 24。如果您决定自定义 maxFramerate
,您应该选择能提供所需结果的最低可能数字。
帧速率控制 Silverlight 控件内的所有内容——动画甚至视频——除了音频。您可以通过将 Great Estates Logo 的 maxFramerate
设置为 1 并将 XAML 文件中的 IsMuted
设置为 false
而不是 true
来实现这一点。这会导致视频以极其卡顿的方式播放,但相应的音频却流畅播放。
maxFramerate 使用的数字必须指定为字符串
与 isWindowless
类似,以下属性设置在调用 createObject
或 createObjectEx
时有效
{ ... , maxFramerate: "24", ... }
但以下设置无效,与大多数人期望的不同
{ ... , maxFramerate: 24, ... }
任何非字符串都被视为每秒零帧!
maxFramerate 与 framerate
您可能会遇到一些 Silverlight 示例,它们设置了 framerate
属性而不是 maxFramerate
。设置 framerate
与设置 maxFramerate
完全相同,并且只能通过 createObject
或 createObjectEx
完成。Silverlight.js 中的逻辑将 framerate
和 maxFramerate
都映射到底层 Silverlight 控件支持的真正 maxFramerate
属性。这样做是为了与 Silverlight 的预发行版本兼容。为了清晰起见,如果您觉得有必要自定义帧速率,请坚持使用 maxFramerate
。
enableHtmlAccess 属性
Silverlight 还支持一个名为 enableHtmlAccess
的属性,但它仅适用于 1.0 之后的版本。它控制 .NET 代码(如 C#)是否能够通过为 .NET 设计的特殊层访问浏览器 DOM。enableHtmlAccess
的默认值为 true
,但它不适用于浏览器托管的 JavaScript,因为 JavaScript 始终可以访问浏览器 DOM。
事件
Silverlight 控件支持两个可以直接在 OBJECT
或 EMBED
元素上设置的事件:onLoad
和 onError
。您可以将任一事件指定为一个要调用的 JavaScript 函数的名称。例如:
<object type="application/x-silverlight" id="silverlightControl"
width="390" height="100">
<param name="background" value="Yellow"/>
<param name="source" value="Chapter1.xaml"/>
<param name="onLoad" value="myFunction"/>
</object>
然而,由于处理这些事件中的任何一个都需要使用 JavaScript,因此您不妨利用 createObject
或 createObjectEx
,而不是以“原始”方式附加这些处理程序。
onLoad
XAML 内容加载完成后立即触发 onLoad
事件。处理此事件对于执行 Silverlight 内容的自定义初始化很有用,例如启动动画或根据文档尺寸动态定位/调整控件大小。这些特定类型的活动将在后续章节中介绍,但列表 1.10 至少演示了如何为 onLoad
事件指定一个函数作为处理程序。
列表 1.10 CreateSilverlight.js — 分配 onLoad 处理程序
function createSilverlight()
{
Silverlight.createObjectEx(
{
source: "Chapter1.xaml",
parentElement: document.getElementById("placeholder"),
id: "silverlightControl",
properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow" },
events: { onLoad: myFunction }
}
);
}
function myFunction(control, context, rootElement)
{
// Perform custom initialization
}
Silverlight 的 onLoad
事件的目的与 HTML DOM 的 onload
事件相似。然而,为了避免时序问题,您应该坚持使用 HTML onload
事件来操作 HTML 内容,并使用 Silverlight 的 onLoad
事件来操作 Silverlight 内容。
传递给 onLoad
事件的处理程序有三个参数:
control
,这是 Silverlight 控件的实例。下一节“以编程方式与 Silverlight 控件进行交互”将描述您可以使用此对象做的一些事情。context
,这仅仅是传递给createObject
或createObjectEx
的任何自定义context
值(如果提供了)。rootElement
,这是source
XAML 内容中根元素的实例。下一章将解释如何以编程方式与 XAML 中声明的 Silverlight 元素进行交互。
onLoad(和 onError)的函数不能指定为字符串!
与大多数属性值中传递的字符串不同,events
关联数组中的元素必须包含对您定义的函数的直接引用(函数指针),如列表 1.10 所示。以下将导致脚本错误:
{ onLoad: "myFunction", ... }
onError
当 Silverlight 抛出您的 JavaScript 代码尚未处理的异常时,将触发 onError
事件。(对于从同步函数调用中抛出的异常,这意味着不存在相应的 try
/catch
块。对于从异步函数调用中抛出的异常,这意味着没有为该特定失败案例附加事件处理程序。)Silverlight 可能因 XAML 解析错误或任何运行时错误而引发异常。
如果您在直接使用 OBJECT
或 EMBED
元素时没有为 onError
指定处理程序,未处理的 Silverlight 错误将被吞没。但是当您使用 createObject
或 createObjectEx
时,一个名为 default_error_handler
的函数将自动设置为 onError
的处理程序,除非您自己提供。默认处理程序调用 JavaScript 的 alert
函数来显示一个简单的对话框,例如图 1.7 中所示的对话框。

当好内容变坏时。
为了理解如何创建自己的 onError
处理程序,查看 Silverlight.js 中 default_error_handler
的实现是很有指导意义的。它的实现如下:
function default_error_handler(sender, args)
{
var errMsg = "\nSilverlight error message\n";
// All errors have a numeric code, a type, and a message
errMsg += "ErrorCode: " + args.errorCode + "\n";
errMsg += "ErrorType: " + args.errorType + "\n";
errMsg += "Message: " + args.errorMessage + "\n";
if (args.errorType == "ParserError")
{
// A parser error gives the location in the XAML content
errMsg += "XamlFile: " + args.xamlFile + "\n";
errMsg += "Line: " + args.lineNumber + "\n";
errMsg += "Position: " + args.charPosition + "\n";
}
else if (args.errorType == "RuntimeError")
{
if (args.lineNumber != 0)
{
// Display the line number and character, if the information exists
errMsg += "Line: " + args.lineNumber + "\n";
errMsg += "Position: " + args.charPosition + "\n";
}
// The name of the function that failed
errMsg += "MethodName: " + args.methodName + "\n";
}
// Display the message in a simple alert box:
alert(errMsg);
}
sender
是发生错误的那个对象,如果适用的话。对于解析错误,例如图 1.6 中所示的错误,sender
为 null
。args
对象提供了许多信息,具体取决于抛出的错误类型,如 default_error_handler
实现所示。
提示 - 尽管有 onError
处理程序,但在 JavaScript 中很容易出错,导致错误未发送到此函数。这些未处理的 JavaScript 错误的行为因浏览器而异。要在 Internet Explorer 中使用 Visual Studio 调试它们,请确保在“Internet 选项”窗格的“高级”选项卡中取消选中“禁用脚本调试”设置!
以编程方式与 Silverlight 控件进行交互
代表 Silverlight 控件的 OBJECT
或 EMBED
元素(无论是静态 HTML 文档的一部分还是由 Silverlight.js 动态注入的)都有一个 HTML id
,因此您可以编写 JavaScript 来检索元素并像其他 HTML 元素一样获取或设置其属性。例如,
// Retrieve the element via a standard HTML DOM function:
var element = document.getElementById("silverlightControl");
// Set properties on the element:
element.width = 500;
element.style.zIndex = 2;
因为这个元素是 ActiveX 对象(或 Netscape 插件)的实例,所以它提供了许多 Silverlight 特有的有用属性、函数和事件。document.getElementById
返回的这个元素与传递给 onLoad
事件处理程序的第一个参数是同一个对象。但是,在控件加载完成(并触发 onLoad
事件)之前,您应该避免访问此对象上的任何 Silverlight 特定成员。
Silverlight 控件主要通过两个属性公开其大部分功能:Settings
和 Content
。
Settings 属性
与本章最相关的是控件的 Settings
属性,它定义了许多子属性,用于获取或设置许多属性(其中许多可以替代地通过 createObject
、createObjectEx
或直接在 OBJECT
/EMBED
元素上设置)
Background
— 前面讨论过的相同属性。然而,这使得随时更改背景颜色变得容易。EnableFramerateCounter
— 一个布尔属性,用于在浏览器状态栏中显示当前帧速率。(这可能对调试有用。)EnableRedrawRegions
— 另一个用于调试的布尔属性,设置为true
时,它会突出显示屏幕上每一帧都会重绘的区域。EnableHtmlAccess
— 前面讨论过的相同属性。MaxFrameRate
— 前面讨论过的相同属性。Windowless
— 与前面讨论的isWindowless
属性相同。
例如,可以在 Silverlight onLoad
事件处理程序中设置 EnableRedrawRegions
和 Background
属性,如下所示:
function myFunction(control, context, rootElement)
{
control.Settings.EnableRedrawRegions = true;
control.Settings.Background = "Red";
}
这些属性以及控件对象上公开的所有其他成员都非常灵活。例如,它们不区分大小写。许多人更喜欢使用小写名称,因为它们符合 JavaScript 约定,如下面的代码所示,该代码产生与前面的代码片段相同的结果:
function myFunction(control, context, rootElement)
{
control.settings.enableRedrawRegions = true;
control.settings.background = "Red";
}
此外,布尔属性可以设置为 true
或 false
字符串或 true
或 false
布尔字面量,并且它们都可以正常工作。
然而,Settings
的成员并不特别引人注目,因为在控件加载后很少需要检索或更改数据。
Content 属性
Silverlight 控件上最常用的成员是其 Content
属性,它表示控件托管的 XAML 内容并公开了一些有趣的功能。它具有以下子属性:
ActualWidth
和ActualHeight
— 报告 Silverlight 控件的尺寸。您可以通过 HTML DOM 发现相同的信息,尽管当浏览器缩放级别(Internet Explorer 的一项功能)不为 100% 时,这些 Silverlight 属性的值与相应的 HTML 属性不同。这些 Silverlight 属性始终报告实际尺寸,而 HTML 属性报告虚拟尺寸(本质上隐藏了缩放级别)。Root
— 当前 XAML 内容中根元素的实例。这与传递给onLoad
的rootElement
参数是同一个对象。(此属性使得rootElement
参数不再是必需的,因为处理程序始终可以使用control.Content.Root
而不是它。)FullScreen
— 使 Silverlight 内容能够填充整个屏幕。为了防止恶意的 Silverlight 应用程序劫持您的屏幕,全屏模式必须由用户操作(例如鼠标单击或按键)启动。因此,此功能将在第 7 章“响应输入事件”中介绍。Accessibility
— 使您能够自定义 Silverlight 控件在辅助功能软件中的显示方式。Accessibility
对象包含三个可设置的属性:Title
、Description
和ActionDescription
(有关更多信息,请参阅第 7 章)。
Content
公开三个函数,这些函数在第 2 章“XAML”和第 8 章“按需下载内容”中进行了介绍
CreateFromXaml
— 在 JavaScript 字符串中动态创建 XAML 指定的 Silverlight 内容。CreateFromXamlDownloader
— 动态创建按需下载的 XAML 文件中指定的 Silverlight 内容。FindName
— 根据分配的名称查找 XAML 中定义的 Silverlight 对象实例。
Content
甚至公开了两种无法以任何其他方式使用的独特事件。例如,您无法在传递给 createObject
和 createObjectEx
的 events
数组中指定它们。这两个事件是:
OnResize
— 每当Content
的ActualWidth
或ActualHeight
属性值更改时引发。OnFullScreenChange
— 每当Content
的FullScreen
属性值更改时引发。
可以通过分配函数引用来附加任一事件的处理程序。列表 1.11 演示了 OnResize
事件。
列表 1.11 CreateSilverlight.js — 分配 OnResize 处理程序
function createSilverlight()
{
Silverlight.createObjectEx(
{
source: "Chapter1.xaml",
parentElement: document.getElementById("placeholder"),
id: "silverlightControl",
properties:
{ width: "390", height: "100", version: "1.0", background: "Yellow" },
events: { onLoad: myFunction }
}
);
}
function myFunction(control, context, rootElement)
{
control.Content.OnResize = function()
{
var htmlElement = document.getElementById("silverlightControl");
alert("Actual Dimensions: " + control.Content.ActualWidth + "x" +
control.Content.ActualHeight);
alert("Virtual Dimensions: " + htmlElement.offsetWidth + "x" +
htmlElement.offsetHeight);
};
}
在此示例中,OnResize
被设置为一个 JavaScript 闭包(在另一个函数内部定义的函数),该函数根据 Silverlight 和 HTML DOM 显示控件的尺寸。如果您尝试使用本章中的任何示例并将其 Internet Explorer 的缩放级别更改为 200%,您会看到 HTML DOM 仍然报告 390x100 的尺寸,而 Silverlight 报告 780x200 的尺寸。虽然 Internet Explorer 不希望 Web 页面知道何时被缩放(因为它们可能会执行干扰正确缩放的奇怪操作),但利用此信息对 Silverlight 内容至关重要,因为控件内的视觉元素不会自动缩放。第 6 章“定位和变换元素”讨论了 Silverlight 内容的调整大小。
其他成员
除了 Settings
和 Content
属性之外,Silverlight 控件还定义了三个属性:
InitParams
— 提供(如果有)为createObject
或createObjectEx
(或直接在OBJECT
/EMBED
元素上)的initParams
参数设置的任何字符串。虽然InitParams
始终作为单个字符串公开给 JavaScript,但逗号分隔列表将被拆分为传递给未来 Silverlight 版本 .NET 代码的字符串数组。IsLoaded
— 报告 Silverlight 内容是否已加载。Source
— 提供控件的source
URL 或#id
值。此属性也可以设置为新的 URL 或#id
值。这会导致控件重新加载新内容,并再次引发onLoad
事件。
控件还直接定义了两个函数:
CreateObject
— 使您能够创建第 8 章所述的下载器对象的实例。IsVersionSupported
— 接受一个包含版本号(如1.0
)的输入字符串,此函数会告诉您已安装的 Silverlight 版本是否与该版本兼容。Silverlight.js 在内部使用此功能来执行版本检查。
控件还定义了一个单独的事件——OnError
——它与前面描述的 onError
事件相同。通过将函数引用分配给控件的 OnError
成员,您可以随时更改默认错误处理程序。请注意,控件没有 OnLoad
成员。您只能使用前面讨论的方法为 onLoad
事件分配处理程序。
结论
随着时间的推移,越来越多的软件被定位到 Web,并且越来越多的软件被期望提供高质量——有时甚至是电影般的体验。然而,过去创建这种用户界面的工作量一直过于巨大。
如果您是软件开发人员,您可能会怀疑除了 HTML 提供的之外,还需要“眼糖”。但无论您是否愿意,拥有引人入胜的用户体验都很重要,无论您是创建面向公众的消费网站,还是为一个简单的内部应用程序。您可以将不切实际的软件归咎于电影和电视,或者可以将其归咎于开始赶上好莱坞标准的实际软件!事实上,现代软件比以前拥有更多的视觉润色。您可以在传统操作系统(如 Mac OS X,以及最近的 Windows Vista)中看到它,在 TiVo 或 Xbox 等设备上的软件中看到它,当然,由于 Adobe Flash,在 Web 上到处都是。用户对使用软件的体验的期望越来越高,公司花费大量时间和金钱在用户界面上,以使自己与竞争对手区分开来。微软深知这一点,这在其最新技术中显而易见——首先是在桌面上的 WPF,现在是在 Web 上的 Silverlight。
Silverlight 使创建引人入胜的 Web 用户界面比以往任何时候都更容易,无论您是想创建一个简单的内容,还是一个值得在夏季大片中扮演角色的沉浸式交互式体验!本章重点介绍了将任何 Silverlight 内容放入网页所需的 HTML 和/或 JavaScript,以及如何自定义嵌入。下一章将深入探讨 XAML 方面,然后本书的其余部分将介绍通过 Silverlight 可以实现的各种内容类型和交互性。