2. Silverlight技术调查
2.1 Silverlight发展史
2.1.1 WPF/E
“WPF/E ”是一种新 Web 呈现技术的代号, 创建该技术的目的是使其能够在各种平台上运行。该技术支持创建丰富的、具有绚丽视觉效果的交互式体验, 并且可以随处实现: 无论是在浏览器内、在多个设备上还是在桌面操作系统( 如 Apple Macintosh) 中。Microsoft .NET Framework 3.0( Windows 编程基础结构) 中的呈现技术 XAML( 可扩展应用程序标记语言) 遵循 WPF (Windows Presentation Foundation), 它是“W PF/E ” 呈现功能的基础。
2.1.2 Silverlight1.0
它着重于促成丰富的媒体场景,下载大小在1.2MB左右。它包括下面一些特性:
1)内置的codec支持,能在浏览器里播放VC-1和WMV视频, MP3和WMA音频。尤其是VC-1 codec, 在把媒体融入web体验方面是个很大的一步,因为它支持播放高达720p(高清晰度)的高品质视频。这个codec格式跟所有的HD-DVD和蓝光DVD播放器支持的格式是一样的,为数于亿计的移动设备,XBOX 360,Windows Media Center和Windows Media Player所支持,这允许 一个人把内容编码一次,在所有这些设备+Silverlight中毫无修改即可使用。这允许你使用庞大的现有视频内容和丰富的编辑工具来生成可用于Silverlight的视频内容。
2)Silverlight支持渐进下载的功能,以及从任何web服务器播放媒体内容的能力。你可以将Silverlight指向任何含有视频/音频内容的URL,它就会下载这些内容,允许你在浏览器里播放这些内容。不需要特别的服务器软件,Silverlight可以与任何web服务器相合作(包括Linux上的Apache)。我们也将发布一些IIS模块,提供你可以在你的服务器上免费启用的有用的媒体控制和带宽控制特性。
3)Silverlight也可支持内置的媒体流广播(media streaming)。这允许你在后端使用一个象Windows Media Server这样的流广播服务器(streaming server),做视频/音频流广播(注:Windows Media Server是运行在Windows Server上的的免费产品)。流广播(Streaming)带来一些非常大的好处: 1) 它可以在用户在一个大的视频流里搜寻时改进用户的体验,2) 它可以极大地降低带宽的成本(大部分用户并不观看整个录像,所以在使用渐进下载时如果他们在视频结束之前离开的话,你就浪费了带宽)。
4)Silverlight允许你创造丰富的UI和动画效果,把矢量图像与HTML混合起来创造出引人入胜的内容体验。它支持一个Javascript编程模型来开发这些效果。一个好处是,它极大地简化了把这些体验集成进AJAX网页(因为你可以编写Javascript同时来更新HTML和XAML元素)。
5)Silverlight使得建造丰富的视频播放器交互体验极其容易。你可以把它的媒体能力与矢量图像支持混合起来创造你想要的任何类型的媒体播放体验。Silverlight包含了全屏的功能来创造一个完全沉浸的体验,以及直接在正播放的视频内容之上覆盖菜单/内容/控件/文字的能力(允许你促成DVD一样的体验)。Silverlight还提供了动态改变正在播放的视频的长宽的功能,而不要求视频流中止或重启。
你可以使用任何标准的文字编辑器来开发Silverlight应用,而不用特别的工具。微软也将通过Expression Studio配套产品发布针对Silverlight 1.0应用的支持,包括内容管理和视频编码的丰富的工具支持。
2.13 Silverlight 1.1
Silverlight V1.1包括下面一些特性:
1) 一个内置的CLR引擎,给浏览器提供了超高性能的运行环境。Silverlight使用和今天我们发布的完整.NET框架一样的核心CLR引擎(是从同一个源码树编译出来的)。它提供了你今天的.NET代码使用的同样的类型系统,垃圾回收器,和JIT代码生成引擎。这意味着你编写出的.NET代码可以在Silverlight,ASP.NET,和 WinForms/WPF Windows应用中运行。它也意味着,你现在可以在浏览器里运行快于解释的 Javascript 250倍的代码。
2) Silverlight包含了一个丰富内置类型的框架库,你可以用来开发基于浏览器的应用。这个框架库是你今天使用的完整的.NET框架类库的子集,允许你很轻松地重用你现有的技能和知识。它包括对集合,泛型,IO,线程,全球化,网络和LINQ的支持。
3) Silverlight包含对WPF UI编程模型的支持。Silverlight 1.1 Alpha版本允许你使用托管代码/事件处理器来对你的UI编程,支持定义和使用封装的UI控件(由任何托管.NET语言开发的)的能力。第一个Silverlight Alpha还没有丰富的内置UI控件 -- 因为我们一直在先忙于建造核心的UI基础设施。但不用担心,将来版本一定会包括丰富的高层次的控件在内的,与此同时,你可以在这里下载一些很棒的控件例程。Silverlight的WPF最终也会发布对象布局管理器和数据绑定这样的核心WPF构造,这些特性在目前的alpha版本里还没有实现,但就要来了。
4) Silverlight提供了一个托管的HTML DOM API,允许你用任何.NET语言对浏览器里的HTML进行编程,这意味着你现在可以使用C#或VB对一个HTML按钮连接一个事件处理器。Silverlight也提供支持,能让HTML页面里的Javascript调用你的Silverlight控件/应用向外呈示的.NET方法。Silverlight包含了一个JSON序列器,支持.NET数据类型与Javascript之间的转换,意味着你可以在Silverlight里使用标准的浏览器Javascript代码调用C#方法,然后让C#返回一个.NET集合,被Silverlight序列化为Javascript集合,为你的浏览器里的Javascript所用。
4) Silverlight不要求后端的web服务器一定要使用ASP.NET,意味着如果你想要的话,你可以把Silverlight与Linux上的PHP一起使用。但是,我们自然会添加一些非常好的特性,允许你轻松地把客户端的Silverlight和服务器端的ASP.NET集成使用。Silverlight 可以使用标准的ASP.NET应用服务(成员,角色,用户信息等等),可以调用ASP.NET提供的WCF或ASMX web服务。
2.1.4 Silverlight2.0 Beta1
Silverlight 2 包含了.NET 框架的一个跨平台,跨浏览器版本,促成了在浏览器中运行的一个丰富的 .NET 开发平台。开发人员可以使用任何一门 .NET 语言(包括VB, C#, JavaScript, IronPython 和 IronRuby)来编写 Silverlight 应用。我们将推出Visual Studio 2008 和 Expression Studio的工具支持,来促成建造 Silverlight 方案时开发人员与美工设计师间良好的工作流和集成。
已经发布的Silverlight 2 Beta1 版本提供了能促成精妙的RIA应用开发的一套丰富的功能集。这些功能包括:
1)WPF UI框架: Silverlight 2包括了一个基于WPF的富客户界面框架,该框架将极大地方便建造丰富的Web应用。其中包括强大的图像和动画引擎,以及对像控件,布局管理,数据绑定,样式和模板皮肤这样高级的UI功能的丰富支持。 Silverligh中的WPF UI框架是与完整的 .NET 框架中的WPF UI框架特性相兼容的一个子集,允许开发人员重用技能,控件,代码和内容来同时建造丰富的跨浏览器的web应用,以及丰富的桌面Windows应用。
2)丰富的控件: Silverlight 2包括了一套丰富的内置控件,可为开发人员和美工设计师用来快速地建造应用。这个即将发布的Beta1版本将包括核心的表单控件(TextBox, CheckBox, RadioButton等),内置的布局管理面板(StackPanel, Grid, Panel等),常见的功能性控件(Slider, ScrollViewer, Calendar, DatePicker等),以及数据操作控件(DataGrid, ListBox等)。内置的控件支持一个丰富的控件模板模型,允许开发人员和美工设计师在一起合作建造精美的解决方案。
3)丰富的Networking支持: Silverlight 2 包含丰富的networking支持。它包括现成调用REST, WS*/SOAP, POX, RSS, 和标准 HTTP服务的支持。它还支持跨域网络访问(允许Silverlight 客户端直接访问网上的资源和数据)。Beta1版本还包含了内置的sockets networking 支持。
4)丰富的基础类库: Silverlight 2 包含了一个丰富的.NET基础功能类库(集合,IO,泛型,线程,全球化,XML,本地储存等)。它包含了允许HTML DOM/JavaScript 与 .NET 代码集成的丰富的API。它还包含了 LINQ 和 LINQ to XML支持(允许对数据的轻松转换和查询),以及本地数据缓存和储存的支持。Silverlight 中的.NET API是完整的 .NET框架的一个兼容子集。
Silverlight 2 不要求.NET框架安装在计算机上就能运行。Silverlight 安装下载包括了在原装的Mac OSX 或 Windows机器上允许上述所有功能(还有我们不久将讨论的更多的功能)所需的一切。
Silverlight 2 Beta1 版本的大小为4.3MB,在没有安装的机器上大概要花4-10秒钟安装。Silverlight 2安装完毕后,你就可以在你喜欢的浏览器(IE, FireFox, Safari等等)里浏览 Web,自动运行丰富的Silverlight应用。
2.2支持的操作系统和浏览器
• Windows Vista with Windows Internet Explorer 7, Firefox 1.5, Firefox 2
· Windows XP SP2 with Internet Explorer 6 or 7, Firefox 1.5, Firefox 2
· Windows Server 2003 (excluding IA-64) with Internet Explorer 6 or 7, Firefox 1.5, Firefox 2
· Windows 2000 with Internet Explorer 6 (Silverlight 2.0 Only)
1. 操作系统
Windows Vista,Windows Server 2003,Windows XP,Windows 2000, Mac OS X 10.4, Mac OS X Leopard; 移动设备。
2. 浏览器
IE 6,IE 7,Firefox 2.0,Firefox 1.5,Safari 2.0,Opera浏览器。
3. 视频和动画支持
使用WMV格式,支持从低分辨率的移动媒体到全屏HD视频,并支持VC-1编码。
Silverlight的安装包本身已经包含了Windows Media的解码技术。因此,在客户端的操作系统中,不需要安装任何Windows Media Player等软件,就可以播放 WMV,VC-1,WMA和MP3等多种从高清质量到移动设备的视频以及音频。
4. 浏览器插件大小 4.38M
2.3 开发部署
2.3.1 A sp.net网页
1) 在页面前面加入一个注册 <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> 2) 加入 ScriptManager控件 <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> 3) 将xap文件放在下面的控件里 <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/DiggSample.xap" Version="2.0" Width="100%" Height="600px" /> |
2.3.2 Html网页
可以采用ActiveX的方法,在页面中放入object标签,设置相应的属性即可。
<!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <head> <script type="text/javascript"> function onErrorHandler(sender, args) { } function onResizeHandler(sender, args) { } </script> </head> <body> <div id="silverlightControlHost"> <object id="SilverlightPlugInID" data="data:application/x-silverlight," type="application/x-silverlight" width="100%" height="100%"> <param name="source" value=" SilverlightApplication1.xap" /> <param name="onError" value="onErrorHandler" /> <param name="onResize" value="onResizeHandler" /> </object> <iframe style='visibility: hidden; height: 0; width: 0; border: 0px'></iframe> </body> </html> |
2.4 数据通信
支持Socket,WCF, WebService,JSON, ADO.NET SERVICE
2.4.1 Socket
注意Beta1中的通信端口号限制:4502-4532。
简单聊天程序示例:
1. 服务端
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(new IPEndPoint(IPAddress.Any, 4502)); socket.Listen(5); while (true) { Socket s = socket.Accept(); Thread t = new Thread(() => { try { while (true) { byte[] buffer = new byte[1024]; int receive = s.Receive(buffer); if (receive != 0) { Console.WriteLine(Encoding.Unicode.GetChars(buffer, 0, receive)); } } } finally { s.Close(); } });
t.Start(); } |
2. 客户端
1) XAML <Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True"> <Grid.RowDefinitions > <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions>
<TextBox x:Name="txtToSend" Grid.Row="0"/> <Button Grid.Row="1" Click="OnSend" Content="Send" Margin="20" /> </Grid>
2)代码
Socket socket; void OnSend(object sender, EventArgs args) { byte[] bytes = Encoding.Unicode.GetBytes(txtToSend.Text); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs() { RemoteEndPoint = new DnsEndPoint( Application.Current.Host.Source.DnsSafeHost, 4502) }; socketArgs.Completed += OnOperationCompleted; socketArgs.UserToken = bytes; socket.ConnectAsync(socketArgs); }
void OnOperationCompleted(object sender, SocketAsyncEventArgs e) { e.Completed -= OnOperationCompleted; byte[] bytes = (byte[])e.UserToken; SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs(); sendArgs.SetBuffer(bytes, 0, bytes.Length); sendArgs.Completed += OnSendCompleted; socket.SendAsync(sendArgs); }
void OnSendCompleted(object sender, SocketAsyncEventArgs e) { socket.Close(); } |
2.4.2 WebClient
该示例中,选择一本书籍之后,我们通过Web Client去查询书籍的价格,并显示出来,最终的效果如下:
1. 编写界面布局,XAML如下
<Grid Background="# 46461F "> <Grid.RowDefinitions> <RowDefinition Height="40"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="40"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Border Grid.Row="0" Grid.Column="0" CornerRadius="15" Width="240" Height="36" Margin="20 0 0 0" HorizontalAlignment="Left"> <TextBlock Text="书籍列表" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20 0 0 0"></TextBlock> </Border> <ListBox x:Name="Books" Grid.Row="1" Margin="40 10 10 10" SelectionChanged="Books_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Name}" Height="32"></TextBlock> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Border Grid.Row="2" Grid.Column="0" CornerRadius="15" Width="240" Height="36" Background="Orange" Margin="20 0 0 0" HorizontalAlignment="Left"> <TextBlock x:Name="lblPrice" Text="价格:" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20 0 0 0"></TextBlock> </Border> </Grid> |
2. 为了模拟查询价格,我们编写一个HttpHandler,接收书籍的No,并返回价格。
public class BookHandler : IHttpHandler { public static readonly string[] PriceList = new string[] { "66.00", "78.30", "56.50", "28.80", "77.00" }; public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Write(PriceList[Int32.Parse(context.Request.QueryString["No"])]); }
public bool IsReusable { get { return false; } } } |
3. 在界面加载时绑定书籍列表
void UserControl_Loaded(object sender, RoutedEventArgs e) { List<Book> books = new List<Book>() { new Book("Professional ASP.NET 3.5"), new Book("ASP.NET AJAX In Action"), new Book("Silverlight In Action"), new Book("ASP.NET 3.5 Unleashed"), new Book("Introducing Microsoft ASP.NET AJAX") };
Books.ItemsSource = books;
} |
4. 接下来当用户选择一本书籍时,需要通过Web Client去获取书籍的价格。
void Books_SelectionChanged(object sender, SelectionChangedEventArgs e) { Uri endpoint = new Uri(String.Format("http://localhost:12345/BookHandler.ashx?No={0}", Books.SelectedIndex));
WebClient client = new WebClient(); client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(endpoint); }
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error == null) { lblPrice.Text = "价格:" + e.Result; } else { lblPrice.Text = e.Error.Message; } } |
2.5 Web交互
1. Silverlight中C#调用HTML DOM/JAVASCIPT
与调用Script(包括Javascript)相关的类型:
System.Object
System.Windows.Browser.ScriptObject
System.Windows.Browser.HtmlObject
System.Windows.Browser.HtmlDocument
System.Windows.Browser.HtmlElement
System.Windows.Browser.HtmlWindow
<Canvas Background="#D5FCDF"> <TextBlock Text="Silverlight Accessing the HTML DOM" Foreground="Red" Canvas.Top="10" Canvas.Left="30" FontSize="18"> </TextBlock> <WatermarkedTextBox x:Name="input" Watermark="请在这里输入" Height="40" Width="300" Canvas.Left="30" Canvas.Top="50"> </WatermarkedTextBox> <WatermarkedTextBox x:Name="result" Watermark="这里显示结果" Height="40" Width="300" Canvas.Left="30" Canvas.Top="100"> </WatermarkedTextBox> <Button x:Name="displayButton" Background="Red" Height="40" Width="100" Content="显 示" Canvas.Top="50" Canvas.Left="350" Click="displayButton_Click"> </Button>
<Button x:Name="callJavascript1" Width="320" Height="40" Background="Red" Canvas.Top="150" Canvas.Left="50" Content="使用GetProperty获取脚本对象" FontSize="20" Foreground="Red" Click="callJavascript1_Click"></Button>
</Canvas>
private void displayButton_Click(object sender, RoutedEventArgs e) { HtmlElement element = HtmlPage.Document.GetElementById(this.input.Text); element.SetAttribute("innerText", this.result.Text); } |
2. Javascript调用Silverlight
在Silverlight 2中提供了如下两个类型:
ScriptableMemberAttribute:允许我们在Silverlight把成员暴露给Script。
ScriptableTypeAttribute:允许我们在Silverlight把类型暴露给Script。
简单加法示例程序,运行界面如下。
1. XAML文件 <StackPanel Background="#CDFCAE" Orientation="Horizontal"> <Border CornerRadius="10" Width="100" Height="40" Margin="50 10 0 0"> <TextBlock Text="结果显示:" FontSize="20" Foreground="Red"></TextBlock> </Border> <Border CornerRadius="10" Background="Green" Width="300" Height="40"> <TextBlock x:Name="result" FontSize="20" Foreground="White" Margin="20 5 0 0"></TextBlock> </Border> </StackPanel>
2. CS文件 private void UserControl_Loaded(object sender, RoutedEventArgs e) { HtmlPage.RegisterScriptableObject("Calculator", this); //注册脚本 }
// 编写一个Add方法,该方法将在JavaScript中被调用,必须为public,用ScriptableMember特性暴露给脚本。 [ScriptableMember] public void Add(int x, int y) { int z = x + y; this.result.Text = String.Format("{0} + {1} = {2}", x, y, z); }
Test.aspx: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="DiggSample_WebServer.WebForm1" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W 3C //DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>无标题页</title> <script type="text/javascript"> function callSilverlight() { var slPlugin = $get('Xaml1'); slPlugin.content.Calculator.Add($get('txt1').value,$get('txt2').value); } </script> </head> <body> <form id="form1" runat="server"> <div > <input id="txt1" type="text" /> <input id="txt2" type="text" /> <input id="Button1" type="button" value="确 定" onclick="callSilverlight()" />
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager>
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/Sample.xap" Version="2.0" Width="100%" Height="600px" /> </div> </form> </body> </html> |
2.6目前开发存在的问题
1. 比WPF应用程序功能要弱。
2. 工具箱内地控件不能直接拖到设计视图中
3. 控件布局方式需要在XAML文件中调整
4. 现在双击控件还不能自动添加事件。需要在XAML文件中感知或代码中手动注册事件。