Silverlight.supportedUserAgent.js - 就一个函数,用于判断 Silverlight 是否支持用户的浏览器,其最新版本在如下地址下载
http://code.msdn.microsoft.com/SLsupportedUA
-->
<
!DOCTYPE html PUBLIC "-//W3C//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
>
<
title
>Silverlight.js
</title>
<
script
type
="text/javascript"
src
="../Silverlight.js"
>
</script>
<
script
src
="../Silverlight.supportedUserAgent.js"
type
="text/javascript"
>
</script>
</head>
<
body
>
<
div
id
="container"
>
<
a
href
="http://go.microsoft.com/fwlink/?LinkID=124807"
style
="text-decoration: none;"
>
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight"
/>
</a>
</div>
两者的技术基础是不一样的。Flash使用不完全二进制格式,而Silverlight是基于WPF的。在被命名为Silverlight之前,它的开发代号为WPF/E(
Windows Presentation Foundation Everywhere)。Silverlight可以到处运行(至少理论上是这样)得感谢好的浏览器支持。
实际上兼容性是浏览器插件的关键问题。在写这本书时,Silverlight插件已经支持Windows平台(这没什么好说的)下的两大浏览器:Microsoft Internet Explorer和Mozilla Firefox
(译者注:火狐浏览器)。还支持苹果机的Mac OS X操作系统使用的两个浏览器Safari和Mozilla Firefox。按照微软的说法,对其他平台的支持正在研究之中,但Windows在桌面操作系统中拥有如此高的市场占有率,而Mac OS X位列第二,所以优先支持这两个浏览器。
事实上,使用一个文本编辑器便能开发Silverlight应用程序,便使用一个“真实”的开发环境能让您事半功倍。最明智的选择是使用微软所提供的开发工具。对于代码编写人员来说,Visual Studio 2005是当前开发Silverlight的最佳选择。无论是完全版本(标准版,专业版,团队开发版)还是免费版的Visual Web Developer Express Edition都可以胜任。如果您使用付费版本,将获得项目模板支持,那是再好不过。本书将使用Visual Studio 2005标准版。无论什么时候,免费的Express版本和付费版本都将有所不同,这尤其重要,它使得用户不会遗漏任何重要信息。
在Windows XP或更高版本上安装Visual Studio或Visual Web Developer无需什么必备条件。您甚至不需要网页服务器,因为IDE已经集成了一个。如果可能,可以安装一个微软的IIS(Internet information Services)。它隐藏在【Software】菜单(译者注:没用过Vista,不知道Software所对应的是不是【软件】菜单)下的控制面板内(Vista操作系统)。如图2-2所示,可以在“turn Windows features on and off”那找到它。(译者注:哪位使用Vista的兄弟帮忙看看这句话的中文是什么)在安装Visual Studio 2005时,请确保选中了“Visual Web Developer”这个选项,如图2-3所示。否则,网页编辑器将不会在IDE内出现。你需要创建网站项目,尽管WPF是一项桌面技术,但Silverlight是一项网页技术。如果您希望使用Visual Studio 2005 Express Edition,可以到以下网址下载一个网络安装版:http://msdn.microsoft.com/vstudio/express/vwd/download/。
如何激活软件的升级取决于您所使用的Windows版本。如果是Windows Vista之前的Windows操作系统,只需要访问以下升级网站(http://update.microsoft.com/microsoftupdate/)进行升级。如果您使用的是Windows Vista,那么单击【开始】菜单,选择【Get updates for more products】链接(译者注:请哪个使用Vista的兄弟帮翻译下这个菜单名)打开如图2-6所示窗口。下次您搜索升级时,便可获得 Visual Studio和其他微软产口的升级补丁。
提示:在安装完
Visual Studio 2005的Server Pack 1后,Vista用户需要再次运行微软的升级以获得一个针对当前操作系统的Visual Studio补丁。
本章未完,待续
Silverlight 4 新特性之Silverlight as Drop Target
在上次项目中写过多篇关于拖拽的实现. 这些拖拽都是控件之间的效果. Silverlight 4 中我们甚至可以直接把文件系统中文件拖拽到Silverlight Application中承载. 这就是 silverlight 4中新特性Silverlight As Drop Target 支持这一点. 为了达到演示目的. 使用桌面图片拖拽到Silverlight Application中ScrollViewer动态显示. 先体验一下[你可以尝试从本地文件系统直接拖拽图片到这个Silverlight Application中看一下效果]:
Silverlight Page Turning Made Simple [silverlight翻页实例 源码 原理 如何使用]
Wicked Code
Silverlight Page Turning Made Simple
Jeff Prosise
Code download available at:
WickedCode2008_05.exe
(1110 KB) Browse the Code Online
Contents
The PageTurnDemo Application
Using the Page-Turn Framework
XAML Structure
Framework Internals
Conclusion
Two years ago,I was cruising down a hallway in Redmond when a friend stopped me. "I have something you need to see," he said. He popped open his laptop and showed me a demo that changed my life. That demo was an early version of the Silverlight
TM Page Turn Sample,which you can see Now at
silverlight.net/samples/1.0/Page-Turn/default.html.
I Couldn't believe what I was seeing because the demo was running—gasp—in a browser! More surprisingly,it didn't require the Microsoft
® .NET Framework,it didn't require Internet Explorer
®,and although no one knew it at the time,one day it wouldn't even require Windows
®.
PageTurn is the quintessential Silverlight 1.0 demo. I use it all the time when I want to impress upon first-timers what Silverlight is all about. But look inside PageTurn and you'll find that building a page-turning application of your own is no small chore. PageTurn relies on transforms,clipping regions,dynamically created XAML objects,and more; the source code requires time and effort (and no small kNowledge of Silverlight) to understand. It deftly demonstrates some of the most prolific capabilities of Silverlight,but it was not necessarily designed for general reuse.
That's why I built a general-purpose page-turning framework that makes it incredibly simple to incorporate page turns into your Silverlight 1.0 applications. With my framework to help out,an entire application can be built with just a few lines of JavaScript. It requires minimal kNowledge of Silverlight itself,and since the entire framework consists of about 500 lines of JavaScript,you can dig in and understand how it works without having to wrap your head around thousands of lines of code. And,of course,you can modify it to your heart's content.
The PageTurnDemo Application
Before I introduce the framework,let's examine an application built around it. The PageTurnDemo application pictured in
figure 1 lets you page through the first several pages of the November 1988 issue of Microsoft Systems Journal,Now kNown as MSDN
® Magazine. (How do you avoid copyright issues when reproducing pages from a magazine? Use pages from the magazine you work with,and use an article you wrote yourself,no less!) Each of the pages is a scanned image,but one of them—the final page—overlays the image with Extensible Application MarkuP Language (XAML) text. I included the text to reinforce a key point: pages fed to the framework aren't limited to just images; with few constraints,they can contain arbitrary XAML,including Images,TextBlocks,MediaElements,and more.
figure 1
PageTurnDemo Shows a Partially Turned Page (Click the image for a larger view)
You can run the demo by downloading the source code and launching it from Visual Studio
® 2008,or you can view it at
wintellect.com/silverlight/pageturndemo. Once the magazine cover appears (a progress bar apprises you of the progress of the download that retrieves all the images used in the app),use the left mouse button to drag the mouse over the cover from right to left to page forward. You can continue dragging left over right-hand pages to reveal more pages,or drag from left to right over left-hand pages to page backward.
How difficult was it to create this sample? Aside from scanning,cropping,sizing the images,and packaging them in a ZIP file,not difficult at all. The three key source code files (which you can find in the download accompanying this column) are the HTML file,the associated JavaScript file,and the XAML file. Take away the code that uses the Silverlight downloader object to download the images,and there's very little source code at all. In fact,only about 10 lines are deVoted to the page-turning functionality.
Using the Page-Turn Framework
PageTurnDemo demonstrates the four basic steps you'll need to complete to use the page-turn framework. The first step is to include PageTurn.js—the script file containing the framework implementation—in the HTML file. Here's the relevant line in Default.html:
copy Code
<script ... src="PageTurn.js"></script>
The second step is to instantiate the framework. Because the page-turn framework is encapsulated in a JavaScript class named PageTurnFramework,the following statement in Default.html.js instantiates the framework:
copy Code
_ptf = new PageTurnFramework(_control,_control.content.findName('PageTurnCanvas'));
The first parameter passed to the PageTurnFramework constructor is a reference to the Silverlight control. The second parameter is a reference to the canvas containing your pages. In PageTurnDemo's XAML document,that canvas is named "PageTurnCanvas."
The third step is to register your pages with the framework. Each page is represented by a canvas,and PageTurnFramework exposes an addPage method that you can call to register pages. AddPage accepts two parameters:
The first parameter is a reference to the canvas representing the left-hand page in a pair of facing pages; the second is a reference to the canvas representing the right-hand page. You can call addPage as many times as you need to register all your page pairs. And then,the final call to addPage must be followed by a call to initializeframework:
copy Code
_ptf.initializeframework();
The initializeframework method initializes the internal state of the framework. Among other things,it creates several XAML objects used to clip and rotate pages,and it also registers handlers for key events.
The fourth and final requirement for using the framework is to be sure to clean up properly. To avoid memory leaks,browser-based apps that programmatically register event handlers should unregister them as well. PageTurnFramework includes a dispose method that deregisters the event handlers registered by addPage and initializeframework. In PageTurnDemo,an onunload attribute in the <body> element calls a local dispose function when the page unloads:
copy Code
<body ... onunload="dispose()">
This local dispose function,which lives in Default.html.js,calls the framework's dispose method:
copy Code
if (_ptf != null)
_ptf.dispose();
I used a DOM event to trigger calls to dispose because Silverlight doesn't fire unload events. You Could just as easily use window.unload events if you'd prefer.
The PageTurnFramework class exposes six public methods that you can call to add page-turning functionality to your apps (see
figure 2). PageTurnDemo uses three of them: addPage,initializeframework,and dispose. The other methods can be used to add extra functionality. For example,if you wanted to include a navigation bar consisting of page thumbnails in your app (as the Silverlight PageTurn demo does),you Could call PageTurnFrame work.goToPage when a thumbnail is clicked to navigate directly to the corresponding page.
figure 2 Page-TurnFramework API
Method
Description
addPage
Registers a page pair with the framework.
dispose
Releases resources held by the framework for proper cleanup.
getCurrentPageIndex
Returns the 0-based index of the page pair currently displayed.
getPageCount
Returns the number of page pairs added with addPage.
goToPage
displays the specified page pair.
initializeframework
Initializes the page-turn framework.
XAML Structure
The page-turn framework imposes a few basic requirements on the structure of XAML documents. Those requirements are:
Represent each page in a page pair with a XAML canvas (a "page canvas").
Include a "page-turn" canvas that is a container for all of the page canvases.
Assign a width,height,and background color (even if it's Transparent) to the root canvas.
The reason for the third requirement is that at initialization,the framework registers a handler for MouseLeave events fired by the root canvas. These events are used to complete page turns if the cursor leaves the Silverlight control with a page partially turned.
As a matter of best practice,all Silverlight 1.0 apps that capture the mouse,as the page-turn framework does when a turn begins,should process MouseLeave events emanating from the root canvas and take that opportunity to release the mouse. And in order for an element to receive mouse events such as MouseEnter and MouseLeave,the element must be "hit testable" within Silverlight. This is done by ensuring that the element (in this case,a Canvas) has a size and that it has a "non null" background.
With these requirements in mind,figure 3 shows the general structure of a XAML document used with the page-turn framework. The page-turn canvas is the one you pass to PageTurnFramework's class constructor. Page canvases are passed to PageTurnFramework.addPage. The page-turn canvas and the page canvases should generally be tagged with explicit widths and heights in order to ensure that the mouse events used by the framework fire properly no matter what kind of XAML content the canvases contain. The rest is just XAML.
figure 3 XAML Structure
copy Code
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="color" Width="width" Height="height">
<!-- Other XAML content goes here -->
<!-- Page turn canvas -->
<Canvas>
<!-- Canvases representing first page pair -->
<Canvas>
<!-- Content for left-hand page goes here -->
</Canvas>
<Canvas>
<!-- Content for right-hand page goes here -->
</Canvas>
<!-- Canvases representing additional page pairs go here -->
</Canvas>
<!-- Other XAML content goes here -->
</Canvas>
The page-turn canvas can happily exist alongside any other rich content in your XAML document. And individual pages can consist of simple XAML images or complex XAML renderings. You should generally avoid using the Clip property of the page canvases because the framework itself uses that property. However,you Could always declare a subcanvas inside a page canvas and use the subcanvas's Clip property to define clipping regions.
If you want the first left-hand page to be blank so that the first right-hand page looks like the cover of an unopened book,simply declare an opaque rectangle in the first left-hand page. Similarly,you can use an opaque rectangle for the final right-hand page to create the appearance of a closed book when the user turns to the last page. PageTurnDemo does both to perpetuate the illusion that you're flipping through the pages of a magazine.
When you scan pages from a book or magazine to use with the page-turn framework,as I did for PageTurnDemo,the scans often have shadows at the inside edges,which give the pages a more realistic appearance. If you don't use scanned images,a bit of XAML can simulate shadows. For the application pictured in
figure 4 (which depicts some of my radio-controlled airplanes and jets and is viewable at
wintellect.com/silverlight/mymodels),I used the XAML rectangles in
figure 5 to create shadows around the vertical divide at the center of each page pair. Alpha values in the GradientStop colors cause the rectangles to fade from right to left on left-hand pages and from left to right on right-hand pages.
figure 5 XAML for Creating Shadows on Page Interiors
figure 4
Page-Turn Sample with XAML Shadows on Page Interiors (Click the image for a larger view)
If any of this is unclear,you can start an application by building from PageTurnDemo. Simply replace my XAML for individual pages with XAML of your own. My page canvases are dimensioned with a width and height of 400 and 544,but you can change those dimensions to whatever you prefer.
Framework Internals
The page-turn framework is implemented in PageTurn.js,which you can see in the download for this issue. The PageTurnFramework class begins just a few lines from the top. JavaScript doesn't support classes,but this framework uses the same prototype pattern used by ASP.NET AJAX and many Silverlight 1.0 apps to simulate classes in JavaScript. It's just an illusion,but it's an effective one.
The class constructor defines all the instance variables—the equivalent of fields in C#—needed to store internal state. For example,the statement
copy Code
this._control = control;
declares a "field" named _control and initializes it with the Silverlight control reference passed to the constructor. In all,approximately 40 fields are declared and used to hold everything from the percent-complete figure for an in-progress page turn (_percent) to tokens representing registered event handlers (which dispose uses to de-register the handlers). Fields also store references to several XAML objects that are created dynamically in initializeframework and to XAML objects registered with calls to addPage.
PageTurnFramework.prototype contains all the PageTurnFramework methods. The methods fall into three broad categories: public methods such as addPage and initializeframework; event handlers,which act in response to the mouse events and Storyboard.Completed events that the framework uses internally; and private methods,which are used internally by the framework but aren't intended to be called from the outside. There's plenty of interesting code,but due to space constraints,you'll have to download PageTurn.js to see them.
One of the interesting aspects of the framework architecture is how it completes page turns if the mouse button is released (or the cursor leaves the control) while a page turn is ongoing. At initialization time,the framework uses createFromXaml to create a Storyboard object to use as a timer. Then it adds the Storyboard to the page-turn canvas (this is one of the reasons you need to pass a reference to the page-turn canvas to the class constructor) and registers a handler for Storyboard.Completed events.
To finish an incomplete page turn,the framework calls Storyboard.begin to start the timer. On each timer tick,it advances the page another increment (using the step size stored in the _step field) and calls Storyboard.begin again if the page turn still isn't complete. You can see this in action by turning a page halfway and then releasing the mouse button. Depending on how far the page was turned when you released it,it will move back to the fully closed or fully opened position.
The Storyboard's XAML deFinition is stored in the variable named _sb in the initializeframework method. You may wonder why that deFinition includes an x:Name attribute whose value is a GUID. In Silverlight 1.0,Storyboards created with createFromXaml must be named or createFromXaml will fail. I had to give the Storyboard a name,but I wanted to make sure the name didn't conflict with other Storyboards used in the application. Therefore,I named it after a GUID.
Another interesting part of the architecture is how the framework uses mouse events. For canvases representing pages,addPage registers handlers for MouseLeftButtonDown,MouseMove,and MouseLeftButtonUp events. A left turn begins when a right-hand page is clicked and progresses as the mouse moves to the left with the left button held down. Similarly,a right turn begins when a left-hand canvas is clicked and progresses as the mouse moves to the right. The key method used by the event handlers is _turnTo,which advances a partially turned page to the position denoted by the percent-complete parameter.
A final aspect of the framework that you may care to examine more closely is how it uses transforms and clipping regions to depict page turns. initializeframework creates two PathGeometry objects: one to serve as a clipping region for right-hand pages and another for left-hand pages. It also creates a TransformGroup object containing a RotateTransform and a TranslateTransform.
figure 6 illustrates how the clipping regions and transforms are used to depict a partially turned page. The red triangle is the clipping region used on the right-hand page that's on top. As the mouse moves to the left,the clipping region grows smaller so that less of the top page is visible and more of the page underneath is revealed. The blue triangle represents the clipping region used on the left-hand page that is revealed as the turn progresses,and the yellow rectangle represents the portion of that page that is clipped out.
figure 6
Clipping Regions and Transforms Used to Depict Page Turns (Click the image for a larger view)
The RotateTransform and TranslateTransform are combined in order to position and orient the page. (Yes,there is a lot of trigonometry involved!) As the mouse moves to the left,imagine the yellow rectangle sliding to the left and rotating into an upright position. Couple that with a mental image of the blue triangle increasing in size while the red one grows progressively narrower and you'll have a pretty good idea of how page turns work.
Conclusion
Before the ink was dry on this column,I thought of other useful additions to the PageTurnFramework API. For example,it might be useful if the framework fired an event every time a page turns so you Could write handlers that update other content on the page. And it Could be useful to expose properties to control key page-turn parameters,such as the width of the shadow that follows turning pages and the step size used to animate incomplete turns.
Feel free to use this framework in your own projects and to modify it. Let me kNow your Feedback,and if you think of useful additions to the feature set and API,let me kNow about that,too. I'll fold in your suggestions with my own and make sure that version 2.0 of the page-turn framework is even better than version 1.0.
Send your questions and comments for Jeff to wicked@microsoft.com.
Jeff Prosise is a contributing editor to
MSDN Magazine and the author of several books,including
Programming Microsoft .NET. He's also cofounder of Wintellect (
www.wintellect.com),a software consulting and education firm that specializes in the .NET Framework. Have a comment about this column? Contact Jeff at
wicked@microsoft.com.