GVKun编程网logo

稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js, Silverlight.supportedUserAgent.js

14

本文将介绍稳扎稳打Silverlight(30)-2.0Tip/Trick之Silverlight.js,Silverlight.supportedUserAgent.js的详细情况,。我们将通过案例

本文将介绍稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js, Silverlight.supportedUserAgent.js的详细情况,。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于Essential Silverlight翻译连载---第二章 Silverlight第一步、Silverlight 4 新特性之Silverlight as Drop Target、Silverlight 5 beta新特性探索系列:1.安装Silverlight 5 beta环境以及OOB模式下Silverlight 5 多窗口支持、Silverlight Page Turning Made Simple [silverlight翻页实例 源码 原理 如何使用]的知识。

本文目录一览:

稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js, Silverlight.supportedUserAgent.js

稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js, Silverlight.supportedUserAgent.js

[索引页]
[源码下载]


稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js,Silverlight.supportedUserAgent.js,自定义启动界面,响应鼠标滚轮事件


作者:webabcd


介绍
Silverlight 2.0 提示和技巧系列
  • Silverlight.js - 一些 js 帮助函数,用于嵌为入 Silverlight 插件以及自定义安装体验等提供帮助
  • Silverlight.supportedUserAgent.js - 就一个函数,用于判断 Silverlight 是否支持用户的浏览器
  • 自定义启动界面 - 三个参数的综合应用:splashScreenSource,onSourceDownloadProgressChanged,onSourceDownloadComplete 
  • 响应鼠标滚轮事件 - 响应并处理鼠标的滚轮事件


在线DEMO
http://www.voidcn.com/article/p-ounmxjds-tq.html 


示例
1、Silverlight.js 和 Silverlight.supportedUserAgent.js 的常用函数的演示和说明
SilverlightDotJsDemo.html
<!--
详解 Silverlight.js    

Silverlight.js - 一些 js 帮助函数,用于嵌为入 Silverlight 插件以及自定义安装体验等提供帮助,其最新版本在如下地址下载
http://code.msdn.microsoft.com/silverlightjs

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>

         < script type ="text/javascript" >

                // Silverlight.createObject() - 生成一个嵌入了 Silverlight 插件的 object 元素
                Silverlight.createObject(
                        "../ClientBin/Silverlight20.xap",// .xap 的地址
                        document.getElementById('container'),// 包含此 object 元素的父元素
                        "slPlugin",// object 元素的 id
                        {
                                width: "100%",
                                height: "100%",
                                minRuntimeVersion: "2.0.31005.0"
                        },// Silverlight 插件的属性数组
                        {
                                onLoad: onslload,
                                onError: onSLError,
                                onSourceDownloadComplete: onSourceDownloadComplete
                        },// Silverlight 插件的事件处理程序数组
                        "key1=value1,key2=value2",// 为 Silverlight 程序传递初始化参数(key=value的形式)。用“,”分隔
                        "myContext" // 上下文信息,可以在插件的 onLoad 事件中获取
                );

                function onslload(plugin,userContext,sender) {
                        alert(plugin.id + " - " + userContext + " - " + sender.toString());
                }

                function onSLError(sender,args) {
                        // args - Sys.UI.Silverlight.ErrorEventArgs 类型
                        // ErrorEventArgs.errorType - 错误类型
                        // ErrorEventArgs.errorMessage - 错误信息
                        // ErrorEventArgs.errorCode - 错误代码

                        // 程序 throw 出的异常可以在此处捕获到
                        alert(args.errorType + "\n" + args.errorMessage + "\n" + args.errorCode);
                }

                function onSourceDownloadComplete(sender,args) {
                        alert("SourceDownloadComplete");
                }


                // Silverlight.createObjectEx(params) - 将所有参数放入一个数组中传入,其内部会解析这个数组中的参数,然后调用 Silverlight.createObject()

                // Silverlight.default_error_handler = function (sender,args){} - onError 事件的默认处理程序,不需要的话可以将其置为 null
                        
         </script>

         < script type ="text/javascript" >

                window.onload = function() {

                        // getSilverlight() - 尝试下载指定的版本,如果指定空字符串 "" 则为尝试下载最新版本
                        // Silverlight.getSilverlight("2.0.31005.0");

                        // isInstalled() - 判断是否安装了指定的 Silverlight 版本
                        alert(Silverlight.isInstalled("2.0.31005.0"));

                        // Silverlight.onSilverlightInstalled - 使用 Silverlight.js 时,如果客户端没有安装 Silverlight 插件,则会自动安装,然后调用此方法以刷新浏览器,可以重写此方法以自定义行为(比如在此通过 createObject() 来使新安装的插件生效,而无需刷新)。注意:如果是 Silverlight 升级,则不会调用此方法,必须重启浏览器(只刷新是不行的)

                        // supportedUserAgent(version,userAgent) - 判断 Silverlight 是否支持用户的浏览器,省略 userAgent 则为当前浏览器
                        alert(Silverlight.supportedUserAgent("2.0"));
                }
        
         </script>

</body>
</html>
 
 
2、自定义 Silverlight 程序的启动界面,并显示加载进度
启动界面的 xaml 文件
SplashScreen.xaml
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Background="Bisque"
>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock Text="Loading" Margin="3" />
                <TextBlock x:Name="percent" Text="0%" Margin="3" />
        </StackPanel>
</Grid>
 
Silverlight 程序全部加载完成前,显示启动界面并显示加载进度
SplashScreen.html
< !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 >SplashScreen </title>
         < style type ="text/css" >
                html,body
                {
                        height: 100%;
                        overflow: auto;
                }
                body
                {
                        padding: 0;
                        margin: 0;
                }
                #silverlightControlHost
                {
                        height: 100%;
                }
         </style>
</head>
< body >
         < div id ="silverlightControlHost" >
                <object id="xaml1" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
                        width="100%" height="100%">
                         < param name ="source" value ="../ClientBin/Silverlight20.xap" />
                        
                         < ! --下载 source 指定的 xap 的过程中所显示的 xaml 的地址-- >
                         < param name ="splashScreenSource" value ="SplashScreen.xaml" />
                        
                         < ! --下载 source 指定的 xap 的过程中所持续调用的事件-- >
                         < param name ="onSourceDownloadProgressChanged" value ="onSourceDownloadProgressChanged" />
                        
                         < ! --souce 指定的 xap 被完全下载后所触发的事件-- >
                         < param name ="onSourceDownloadComplete" value ="onSourceDownloadComplete" />
                 </object>
                 < iframe style ='visibility: hidden; height: 0; width: 0; border: 0px' > </iframe>
         </div>

         < script type ="text/javascript" >
        
                function onSourceDownloadProgressChanged(sender,args) {
                        // progress 属性 - 下载进度(0 - 1 之间)
                        sender.findName("percent").Text = Math.round(args.progress * 10000) / 100 + "%";                        
                }

                function onSourceDownloadComplete(sender,args) {
                        sender.findName("percent").Text = "100%";
                }

         </script>

</body>
</html>
 
 
3、响应并处理鼠标的滚轮事件
Wheel.xaml
<UserControl x:
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel>
                <TextBox x:Name="lblMsg" />
        </StackPanel>
</UserControl>
 
Wheel.xaml.cs

/*

* 如何响应鼠标滚轮事件,可以参看 Deep Zoom Composer 生成的 MouseWheelHelper.cs

*/


using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;


using System.Windows.browser;


namespace Silverlight20.Tip

{

         public partial class Wheel : UserControl

        {

                 public Wheel()

                {

                        InitializeComponent();


                         this.Loaded += new RoutedEventHandler(Wheel_Loaded);

                }


                 void Wheel_Loaded( object sender,RoutedEventArgs e)

                {

                        HtmlPage.Window.AttachEvent( "DOMMouseScroll",OnMouseWheel);

                        HtmlPage.Window.AttachEvent( "onmousewheel",OnMouseWheel);

                        HtmlPage.Document.AttachEvent( "onmousewheel",OnMouseWheel);

                }


                 private void OnMouseWheel( object sender,HtmlEventArgs args)

                {

                        args.PreventDefault();


                         double mouseDelta = 0;

                        ScriptObject eventObj = args.EventObject;


                         // Mozilla and Safari    

                         if (eventObj.GetProperty( "detail") != null)

                        {

                                mouseDelta = (( double)eventObj.GetProperty( "detail"));

                        }


                         // IE and Opera        

                         else if (eventObj.GetProperty( "wheelDelta") != null)

                        {

                                mouseDelta = (( double)eventObj.GetProperty( "wheelDelta"));

                        }


                         // IE浏览器:mouseDelta == 120 向上滚动;mouseDelta == -120 向下滚动

                         // FF浏览器:mouseDelta == -3 向上滚动;mouseDelta == 3 向下滚动

                        lblMsg.Text += mouseDelta.ToString();

                }

        }

}
 

OK
[源码下载]

Essential Silverlight翻译连载---第二章 Silverlight第一步

Essential Silverlight翻译连载---第二章 Silverlight第一步

第二章 Silverlight第一步
关于Silverlight
一些人把Silverlight技术称为“Flash杀手”,但我不能确信这是否真实。无论如何,两者非常相似。无论是Adobe公司的Flash(以前是Macromedia公司的Flash)还是Silverlight都作为浏览器插件。两者都支持矢量图形,声音和视频回放,动画和脚本支持。
两者的技术基础是不一样的。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需要运行在Windows XP或更高的版本上;但1.0版本有可能在某一时间升级为支持Windows 2000的版本。在未来版本中也将增加对Opera浏览器的支持;当前它是第三大浏览器,拥有相对较少但非常忠实的用户。
 

提示:专业的绘图软件如 Adobe的Photoshop使用了几个复杂的算法来保证当图像尺寸改变时的质量损失(特别当缩小图像时);然而,当图像放大时,对图像的影响还是很明显的。
Mono 项目( http://www.mono-project.com/ ),因为开源并运行 .NET 而闻名,它可以在 Linux 平台的 Firefox 浏览器下运行开源的 Silverlight 端口。这个项目被称为 Moonlight (请见 http://www.monoproject.com/Moonlight )。 http://www.mono-project.com/MoonlightShots 网站也有一些最新的成果的一些效果图(图 2-1 )。微软也宣布将联合 Novell (译者著:一种操作系统) 派出一个小组支持 Moonlight 项目并把它移植到 Linux 下。
但除了做为浏览器插件之外, Silverlight 还有什么过人之处呢?这个插件的最主要部份是支持 WPF 子集(详情请见第 4 章)的图形子系统。它还包含了表现视频和音频的代码(请参考第 7 章了解更多关于多媒体方面的内容)。
Silverlight 的体系非常复杂(请参考 http://msdn2.microsoft.com/en-us/library/bb404713.aspx )。主要可以分为两大块,表现层负责处理 UI ,包括动画,文字渲染和音频 / 视频回放。插件被整合在浏览器内使得这些内容可见,并且也可以通过 JavaScript DOM 访问。最后,使用 JavaScript 代码(如果使用 ASP.NET AJAX 框架就更好了) Silverlight 应用程序就可以象 web services 一样访问服务器 API 了。图 2-2 (译者注:很遗憾,本书并不存在我们想要的这张图,这里是一个错误) 展现了这个体系。 Silverlight1.1 将对这些做进一步地扩展,并把 .NET Framework 的一部份整合进 Silverlight 内。
安装Silverlight开发系统
 

事实上,使用一个文本编辑器便能开发 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/
 

无论您安装的是 Visual Studio 的哪个版本,都应该立即安装一些有用的补丁(在写本书时最新的补丁是 Service Pack 1 ), Windows Vista 用户必须安装一个专门针对 Vista 用户的升级补丁。在安装期间,需要注意 Vista 的一个很出名的软件运行问题,解决方法是安装所有可用的补丁,如图 2-4 所示。
 

大概给微软产品安装最新补丁的最便利的方法就是使用 Windows 自动更新机制。微软的软件更新是一个长期服务。 Windows 自动更新不但给 Windows 和它的核心组件如 Internet Explorer 打补丁,还给其它的一些微软产口包括 Office Visual Studio ,和 sql Server 打补丁。如图 2-5 所示。

 
    如何激活软件的升级取决于您所使用的 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 as Drop Target

在上次项目中写过多篇关于拖拽的实现. 这些拖拽都是控件之间的效果. Silverlight 4 中我们甚至可以直接把文件系统中文件拖拽到Silverlight Application中承载. 这就是 silverlight 4中新特性Silverlight As Drop Target 支持这一点. 为了达到演示目的. 使用桌面图片拖拽到Silverlight Application中ScrollViewer动态显示. 先体验一下[你可以尝试从本地文件系统直接拖拽图片到这个Silverlight Application中看一下效果]:

实现步骤:

<1>: 页面布局

 
 
  1. <StackPanel x:Name="LayoutRoot" Background="White">  
  2.          <TextBlock Text="  "></TextBlock>  
  3.          <TextBlock Text="Silverlight AS Drop target.-chenkai[10.6.28]" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="16" Foreground="Red"  FontFamily="Comic Sans MS" FontWeight="BOld" Height="25" Width="655" />  
  4.          <ScrollViewer x:Name="ImagesTarget" Background="White"  Height="360" BorderBrush="Red" 
  5.                        VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Auto" AllowDrop="True">  
  6.                  <ItemsControl x:Name="ImageList" Height="353">  
  7.                      <!--定义数据模板 支持格式是Image图片 很重要 不然会包invaid异常 数据模板确实很强大.-->  
  8.                      <ItemsControl.ItemTemplate>  
  9.                          <DataTemplate>  
  10.                              <Image Source="{Binding}" Margin="5" Stretch="UniformToFill" Height="240" />  
  11.                          </DataTemplate>  
  12.                      </ItemsControl.ItemTemplate>  
  13.                      <!--项排序模式Horizontal 居中-->  
  14.                      <ItemsControl.ItemsPanel>  
  15.                          <ItemsPanelTemplate>  
  16.                              <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"/>  
  17.                          </ItemsPanelTemplate>  
  18.                      </ItemsControl.ItemsPanel>  
  19.                  </ItemsControl>  
  20.              </ScrollViewer>  
  21.      </StackPanel> 

<2>:后台实现代码

 
 
  1. //定义存储Image集合.  
  2.          ObservableCollection<BitmapImage> _images = new ObservableCollection<BitmapImage>();  
  3.    
  4.          public MainPage()  
  5.          {  
  6.              InitializeComponent();  
  7.              this.Loaded += new RoutedEventHandler(MainPage_Loaded);  
  8.          }  
  9.    
  10.          void MainPage_Loaded(object sender, RoutedEventArgs e)  
  11.          {  
  12.              //如果Image数据则直接加载进来.  
  13.              ImageList.ItemsSource = _images;  
  14.              ImagesTarget.Drop += new DragEventHandler(ImagesTarget_Drop);  
  15.          }  
  16.          void ImagesTarget_Drop(object sender, DragEventArgs e)  
  17.          {  
  18.              //判断拖拽数据是否存在  
  19.              if (e.Data == null)  
  20.              {  
  21.                  return;  
  22.              }  
  23.              else 
  24.              {  
  25.                  //利用Fileinfo 来初始化关于文件系统日常操作io对象 Fileinfo 【】数组 意味支持多张Image同时拖拽Silverlight Application  
  26.                  IDataObject dataObject = e.Data as IDataObject;  
  27.                  FileInfo[] files =dataObject.GetData(DataFormats.FileDrop) as FileInfo[];  
  28.    
  29.                  foreach (FileInfo file in files)  
  30.                  {  
  31.                      try  
  32.                      {  
  33.                          using (var stream = file.OpenRead())  
  34.                          {  
  35.                              //读取拖拽中图片源.  
  36.                              var imageSource = new BitmapImage();  
  37.                              imageSource.SetSource(stream);  
  38.                              //添加到集合中.  
  39.                              _images.Add(imageSource);  
  40.                          }  
  41.                      }  
  42.                      catch (Exception)  
  43.                      {  
  44.                          MessageBox.Show("Not a suppoted image.");  
  45.                      }  
  46.                  }  
  47.              }  
  48.          }  

因为前台ScrollView中DataTemplate中定义格式是Image绑定. 后台数据源用到ObservableCollection<BitmapImage>来封装从拖拽中得到图片数据. 另外一个就是FileInfo,提供创建、复制、删除、移动和打开文件的实例方法,并且帮助创建 FileStream 对象,既然通过Fileinfo得到FileStream对象 其他操作就是平常IO操作. 而Fileinfo[]数组则是用来支持同时拖拽多个对象.关于Fileinfo 更多详细资料请参见MSDN.

Silverlight 5 beta新特性探索系列:1.安装Silverlight 5 beta环境以及OOB模式下Silverlight 5 多窗口支持

Silverlight 5 beta新特性探索系列:1.安装Silverlight 5 beta环境以及OOB模式下Silverlight 5 多窗口支持

        Silverlight 5 beta版本总算于昨日放出,怀着激动的心情今天将开发环境更新为Silverlight 5 beta版本,并且接触Silverlight 5 beta的第一个新特性:OOB模式下的多窗口的弹出显示。

        现在我们开始Silverlight 5 Beta版本的安装,首先需要为VS2010打一个VS2010 SP1补丁,然后我们再下载Silverlight 5 Beta Tools for Visual Studio SP1,一步一步安装完毕,最后我们下载Silverlight 5 Features Document 新特性的文档。至此我们即可踏上Silverlight 5开发的征程。

        对于Silverlight 5 beta版本下面的新窗口的支持是基于OOB模式下的,所以我们首先新建一个Silverlight 5的应用程序,然后右键项目属性-->"允许浏览器外运行应用程序"勾中-->点击"浏览器外设置"-->"在浏览器外运行时需要提升 的信任"勾上。如下图所示:

        然后我们在后台代码中键入以下代码即可弹出一个窗口,点击窗口中的按钮我们可以继续弹出窗口,实现了无限制的弹出窗口。当然所有弹出的子窗口都是依赖于父 窗口而存在的。(Tip:在Silverlight 4.0中的Window类修改的大小都是自身窗口的大小,并不能弹出窗口)

 

  
  
  1. public partial class MainPage : UserControl 
  2.   { 
  3.       public MainPage() 
  4.       { 
  5.           InitializeComponent(); 
  6.           PopWindow(400.0, 20.0, "第"+Flag+"个实例窗口"); 
  7.       } 
  8.       public static int Flag = 0; 
  9.       private void PopWindow(double left,double top,string title ) 
  10.       { 
  11.           //设置Window的通用属性 
  12.           Window testwindow = new Window(); 
  13.           testwindow.Height = 400; 
  14.           testwindow.Width = 500; 
  15.           testwindow.Top = top
  16.           testwindow.Left = left
  17.           testwindow.Title = title; 
  18.           testwindow.Visibility = Visibility.Visible; 
  19.  
  20.           //添加一个内部有按钮的Canvas,设置Canvas的背景色为白色 
  21.           Button btn=new Button(); 
  22.           btn.Width=80.0; 
  23.           btn.Height=30.0; 
  24.           btn.Content="点  击"
  25.           btn.Margin = new Thickness(5, top + Flag * 10, 0, 0); 
  26.           btn.Click += new RoutedEventHandler(btn_Click); 
  27.           Canvas canvas = new Canvas(); 
  28.           canvas.Children.Add(btn); 
  29.           canvas.Background = new SolidColorBrush(Colors.White); 
  30.           testwindow.Content = canvas; 
  31.  
  32.           //窗口默认值是WindowState.normal正常情况 
  33.           testwindow.WindowState = WindowState.normal; 
  34.               //WindowState.Maximized; 窗口最大化 
  35.               //WindowState.Minimized; 窗口最小化 
  36.               //WindowState.normal;    普通窗口 
  37.  
  38.       void btn_Click(object sender, RoutedEventArgs e) 
  39.       { 
  40.           PopWindow(400.0, "第"+Flag+"个实例窗口"); 
  41.       } 
  42.   } 

        本实例采用VS2010 +Silverlight 5 beta制作,如需源码请点击 SL5First.zip 下载。

Silverlight Page Turning Made Simple [silverlight翻页实例 源码 原理 如何使用]

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:
copy Code
_ptf.addPage(_control.content.findName('EvenPage0'),_control.content.findName('OddPage0'));
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:
  1. Represent each page in a page pair with a XAML canvas (a "page canvas").
  2. Include a "page-turn" canvas that is a container for all of the page canvases.
  3. 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
copy Code
<!-- Shadow on left-hand page -->
<Rectangle Canvas.Left="380" Canvas.Top="0" Width="20" Height="600">
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
            <GradientStop Color="#00000000" Offset="0.0" />
            <GradientStop Color="#40000000" Offset="1.0" />
        </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

<!-- Shadow on right-hand page -->
<Rectangle Canvas.Left="0" Canvas.Top="0" Width="20" Height="600">
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0">
            <GradientStop Color="#40000000" Offset="0.0" />
            <GradientStop Color="#00000000" Offset="1.0" />
        </LinearGradientBrush>
    </Rectangle.Fill>
</Rectangle>

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.
转自:http://msdn.microsoft.com/en-us/magazine/cc507644.aspx
@H_301_486@

我们今天的关于稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js, Silverlight.supportedUserAgent.js的分享就到这里,谢谢您的阅读,如果想了解更多关于Essential Silverlight翻译连载---第二章 Silverlight第一步、Silverlight 4 新特性之Silverlight as Drop Target、Silverlight 5 beta新特性探索系列:1.安装Silverlight 5 beta环境以及OOB模式下Silverlight 5 多窗口支持、Silverlight Page Turning Made Simple [silverlight翻页实例 源码 原理 如何使用]的相关信息,可以在本站进行搜索。

本文标签:

上一篇稳扎稳打Silverlight(30) - 2.0Tip/Trick之Silverlight.js, Silverlight.supportedUserAgent.js, 自定义启动界面, 响应鼠标滚轮事件

下一篇RippleDrawable-以编程方式显示纹波效果