Silverlight与AJAX的融合
来源:eNet硅谷动力
你还记得在AJAX(异步JavaScript和XML)技术出现之前,Web应用程序是什么样子吗?尽管AJAX被广泛使用只有一年的时间,但现在人们已经不愿使用AJAX出现之前的Web应用程序。随着AJAX变得越来越像一个技术标准而不仅仅是昙花一现,Silverlight 正在对Web技术重新下定义。
对许多资深的技术开发人员来说,AJAX无非就是一个XMLHTTPRequest对象。不过,对最终用户而言,AJAX使用户于服务器的交互更加流畅,并且AJAX还具有一些新的功能,比如自动完成和动态显示,这些体验都是之前的网络浏览器所不能提供的。AJAX打破了用户体验(UX)的障碍,AJAX技术使得Web开发人员都成为了超级巨星。然而,就像DHTML以及过去的其它技术,AJAX的局限性很快也出现了。为了继续改善用户的Web应用的体验,我们必须再次突破目前的障碍,这也正是Silverlight准备要做的。
就其核心部分而言,Silverlight只不过一个浏览器插件。但是看过技术细节后,你就会开始明白这种技术是多么的强大。就像之前的技术一样, Silverlight是建立在AJAX之上,而不是要取代它。这个核心的概念非常重要,因为这可以让开发团队继续利用其现有的代码库,而不需要经历一个彻底的程序重写。当你想要修改一个现有的HTML元素让它更加吸引人时,这特别有用。通过将Silverlight背景层在你的现有元素上,你可以改善你应用程序的外观,而不必重新修改原有代码。Silverlight包含的一些重要功能,比如灵活的编程模型以及无窗口属性使得上述功能得以实现。
灵活的编程模型
将Silverlight集成到一个Web应用程序首先是Silverlight托管。该托管仅仅是Silverlight插件的一个展示它负责将MAML内容输出到屏幕上。Silverlight的一个核心的功能,就是能够在多种语言环境下对XAML进行编程,包括Javascript、Jscript、C#、VB,甚至Iron Python。Silverlight对多种语言的支持的支持,使你可以根据自己的需要灵活选择合适的工作环境。既然你可以指定提供应用程序行为和事件处理的外部代码文件,所以你可以使Silverlight代码文件同工程的其它代码文件完全分开。这个功能很重要,因为它可以让你轻松的在现有的应用程序中添加Silverlight功能,同时又不改变现有的程序逻辑,或者因为意外更改代码而不至于很难找到由此带来的软件缺陷。
添加SilverLight
Silverlight Host对象可以用不同的方式添加到您的网页数上。当使用ASP.NET AJAX工作时,你最好的选择将是使用包含在ASP.NET Futures中的新的“Xaml”控件。该Xaml控件代表Silverlight host 对象,它还有一个XamUrl属性,该属性用来指出Xaml文件的位置,具体如何使用请见例子1。当网页在浏览器显示的时候,由XamUrl属性指示的Xaml文件会被Silverlight Host对象加载。
<asp:Xaml XamlUrl="default.xaml" runat="server"
CssClass="txtBoxWrapper" Width="120px" Height="20px"
BackColor="transparent" SilverlightBackColor="transparent"
Windowless="true" ClientType="Wrappers.TextBox">
<Scripts>
<asp:ScriptReference Path="default.xaml.js" />
</Scripts>
</asp:Xaml>
例子 1
通过Xaml空间的脚本集合,你可以添加事件处理代码文件。这完全符合AJAX应用程序的共同编程风格,并且使你能够在客户端创建于服务器端某些功能相对的JavaScript控件。
无窗口互用性
要将Silverlight真正集成到AJAX应用程序,接口部分必须可以协调工作。过去的浏览器插件作为窗体控件执行时,一般会出问题。这方面的一个例子是Internet Explorer 的DropDown控件(HTML 元素)。DropDown可以透过任何放置在它上面的HTML元素。这是因为DropDown在Internet Explorer里一开始就是作为窗体控件 。而在Internet Explorer 7中,这种情况已经发生了改变。因为窗体永远在非窗体控件之上绘制,设置z-index参数是没有效果的。幸亏地是,Silverlight托管提供了窗体属性,让你可以启动该功能,以满足您的需要。而我希望Silverlight托管在元素层上可以互动,因此,我在例子1中将Windowless属性设为true。
拼接起来
在现有的HTML元素上将Xaml背景分层,使得在应用程序上以增量方式增强Silverlight用户体验成为可能。这个方法可以让你按照自己的速度实施Silverlight,而不是被强迫一次完成所有工作或者什么都不敢干。使用CSS定位你的canvas背景,JavaScript使得你的背景显得很逼真,对于AJAX 开发人员来说,只有XAML是陌生的。幸运地是,陈述性标记语言对ASP.NET开发人员来说并不是什么新鲜事物,微软的Expression Blend 2使得仅仅通过简单的点击就能创建动画。
创建背景
掌握了基本概念和并拥有开发工具,你可以很容易地为你现有的AJAX应用程序建立一个Silverlight交互层。一个毫无疑问的可以进行一些装饰的控件是经典的TextBox控件。这不仅仅是因为该控件的标准外观相当灰暗,而且在不同的操作系统或者浏览器下,它的外观也是不同的。这对于那些希望自己设计的接口在任何环境下都看起来一样的设计师们来说简直就是噩梦。 CSS技术成为了最常见的式样标准,但它的分隔符最终会让你感到厌烦。 Silverlight是改变这种状况的一个有效的方法。第一步就是为TextBox控件创建一个XAML皮肤。请记住,你创造了一个装饰层,它会被放在现有的HTML元素之上,因此不同的层使用不同的透明度是很重要的。在例子2中,通过绘制矩形并为增加视觉效果添加了storyboard,这就创建了Xaml标记。请记住,Silverlight
背景将会被层叠在现有的HTML TextBox上面,TextBox与背景匹配的程度是很重要的。
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Scene"
Width="120" Height="20"
>
<Canvas.Resources>
<Storyboard x:Name="animation">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#00FFFFFF"/>
<SplineColorKeyFrame KeyTime="00:00:01" Value="#991E1C1C"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:01" Value="#FFFFF9F9"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<Rectangle Width="120" Height="20" Fill="#FFFFFFFF"
Stroke="#FF000000" Canvas.Left="0" Canvas.Top="0"
MouseEnter="MouseEnter" x:Name="rectangle"/>
</Canvas>
例子 2
定位背景
创建完Xaml层后,是时候使用一些CSS式样将背景放在现有的TextBox上了。通过把TextBox和Xaml控件放在一个相对位置容器中,你可以像例子3那样,将一个层叠在另一个上。一旦把背景层叠在TextBox上时,调整背景颜色增加透明度就很重要了。WebControls具有传统的CssClass属性 ,Xaml 同样有一个SilverlightBackColor属性。这个属性必须设置成透明,以揭示它下方的层。
动态插入
如果你想避免修改您现有的ASPX/HTML页面,你可以动态地向你的网页添加Xaml控制。这可以通过扩展TextBox控制,并在控制集合中添加Xaml控制来实现。因为一个TextBox一般没有子类,你还需要重载Render方法,并Xaml控制中显式调用RenderControl。你也可以在Render方法里添加DIV元素,这将会封装TextBox 和 Xaml元素。
你可以让ASP.NET自动将framework的TextBox控件替换成你自己编写的新派生的类,而不需要手工替换。通过使用web.config文件的TagMappings部分,可以实现上述功能。按照这一办法,你可以将你的所有Silverlight代码与项目现有的其它代码完全分开。这不仅使得维护方便,它还可以使您在网页中添加智能开关逻辑,如果某些条件得到满足,将只加载特定的SilverLight层。
<div style="width:120px;height:20px;position:relative;">
<asp:TextBox ID="TextBox1" runat="server" CssClass="txtBox">
</asp:TextBox>
<asp:Xaml XamlUrl="default.xaml" runat="server"
CssClass="txtBoxWrapper" Width="120px" Height="20px"
BackColor="transparent" SilverlightBackColor="transparent"
Windowless="true" ClientType="Wrappers.TextBox">
<Scripts>
<asp:ScriptReference Path="default.xaml.js" />
</Scripts>
</asp:Xaml>
</div>
例 3
赋予背景以新的生命
当完成HTML/ASPX 和XAML全部完成后,JavaScript就是唯一剩下的一部分了。如果你看回过头来看看例子2,你将通会发现添加了一个Storyboard对象,到目前为止它还没有被激活。你可以通过使用JavaScript 添加mouseEnter事件对它进行激活,这是通过JavaScript addEventListener函数实现的。你可以像例子4中那样,使用findName函数得到Storyboard对象的指针。一旦你获得了Storyboard对象的指针 ,通过调用开始方法你就可以绘制动画。JavaScript文件会由Silverlight Host对象自动加载,只要你在Xaml控件的Scripts集合中指明脚本指针就行了(见例子3 )。在JavaScript文件文件里定义表示客户端的对象,Xaml控件中的 ClientType属性必须被设定为对JavaScript 文件 的registerClass调用中制定的类型,具体使用参见例子4的最后一行。
Type.registerNamespace("Wrappers");
Wrappers.TextBox = function(element) {
Wrappers.TextBox.initializeBase(this, [element]);
}
Wrappers.TextBox.prototype = {
_events: null,
xamlInitialize : function() {
Wrappers.TextBox.callBaseMethod(this, 'xamlInitialize');
// Hookup mouseEnter and mouseLeftButtonUp events
var func = Function.createDelegate(this, this._animate);
var rectangle=this.get_element().content.findName("rectangle");
// Use mouseEnter to begin our Storyboard animation
this.addEventListener(rectangle,"mouseEnter", func);
// Use mouseLeftButtonUp to transfer focus to our TextBox
func=Function.createDelegate(this,this._transferFocus);
this.addEventListener(rectangle,"mouseLeftButtonUp",func);
},
_animate : function(sender, e) {
sender.findName("animation").begin();
},
_transferFocus : function(sender, e){
$get("TextBox1").focus();
}
}
Wrappers.TextBox.registerClass('Wrappers.TextBox', Sys.Preview.UI.Xaml.Control);
例子4
在准备好JavaScript文件以及动画被激活之后,还有一项事情要做。因为背景是层叠在TextBox上面的,点击该TextBox 不会传递焦点。你需要给手工给TextBox添加一个mouseLeftButtonUp事件处理,从而当鼠标点击时,焦点可以传递给该TextBox。在例子4中,_transferFocus函数展示了该功能。
AJAX 和Silverlight
用户体验是应用程序一个重要环节,这种观念最近迅速得到大家的认可。AJAX是一个有效的方法,它有助于打破网络应用程序性能和可用性方面的障碍。不过,虽然CSS 和JavaScrip给我们提供了式样和整体视觉吸引力,但是我们还是局限于使用浏览器得以核心要素。JavaScript的动画效果非常有限,并且随着它们变得越来越复杂,有时候它们会很不连贯,而且在许多情况下它们给浏览器代来的负担过重使得不能相应客户端浏览器。一个反应迟钝的浏览器是用户体验的最可怕的杀手。而要突破视觉障碍,就需要Silverlight这样的技术。虽然完全使用Silverlight创建一个项目是可能的,然而在很多的情况下,这是不是没有必要的,甚至是不可行的。相反,将Silverlight层叠再你现有的应用上,你可以将用户体验提高一个层次,并且不用花费宝贵的时间和金钱去重写代码。