详解Silverlight 3.0 RTW新特性

开发 后端
Silverlight 3.0 RTW新特性中引入了一个人们期待已久的事件 -- 鼠标滚动事件,处理这个事件非常简单,只需要根据方向指定正负值和滚动的数量即可。本文主要介绍如何创建行为,如何使用鼠标滚动事件,以及如何将其添加到可滚动的控件上,以便使用鼠标滚轮。

在Silverlight 3.0 RTW新特性中,展示一个鼠标滚动事件的示例只需要几行代码即可,我认为大部分人都可以在几分钟内做好,并理解它是如何工作的。因此我决定将这个事件和Expression Blend中引入的新行为一起合并成一个例子进行介绍。

行为是什么?

你可能曾经在ASP.NET Ajax框架中使用过行为,说得简单点这里的行为就是ASP.NET Ajax语法的Silverlight实现,允许创建可复用的和可连接到HTML控件的行为。(Silverlight 3.0 RTW新特性让操作简单的和手工具)

从Blend 3 Beta版开始引入行为的概念,可以在设计窗口中拖动内置的行为,增加图形元素的活力,进入Asset文件夹,在这里可以找到控件、效果、资源和其它东西,现在又多了一个行为卡片。

Expression Blend 3.0 引入了许多行为类型,行为< T>是其中最简单的了,适用于DependencyObject,行为可以修改控件的外观,添加元素,修改属性或处理一个或多个事件。MouseDragElementBehavior就是一个活生生的例子,它连接鼠标事件,让元素可以在页面中拖动。

编写一个行为

编写一个行为是一件很简单的事情,行为是行为< T>的类扩展,因此首先要做的是引用C:\Program Files\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight目录下的Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll。如果你从Blend 3.0添加一个现有的行为,那这些动态库会自动引用到项目中。

引用添加好后,就可以创建类了:

  1.  public class MouseWheelScrollBehavior : Behavior< Control>   
  2. {  
  3. // 在这里添加实现代码  

由于我们是要扩展Silverlight中可滚动的组件,我们需要创建一个可以连接到Control类的类型,在Silverlight中没有通用的用于可滚动组件(如ScrollViewer、DataGrid和DataGrid)的类,这就需要自己想办法处理才行,我们将在后面进行介绍,目前先分析一下如何创建一个行为。(微软Silverlight中加入Smooth Streaming)

接下来要做的是在目标对象上连接MouseWheel事件,当我们完成行为类的扩展后,我们有两个办法来处理连接和释放目标上的行为:将行为连接到对象上时调用OnAttached,释放对象上的行为时使用OnDetaching。OnAttached和OnDetaching是连接和释放公共事件的理想选择,目标对象是通过行为< T>在AssociatedObject属性上暴露的,下面是我的代码示例:

  1.  /// < summary>   
  2. /// Called after the behavior is attached to an AssociatedObject.  
  3. /// < /summary> 
  4. /// < remarks>Override this to hook up functionality to the AssociatedObject.< /remarks> 
  5. protected override void OnAttached()  
  6. {  
  7. this.AssociatedObject.MouseWheel += new MouseWheelEventHandler(AssociatedObject_MouseWheel);  
  8. base.OnAttached();  
  9. }  
  10. /// < summary> 
  11. /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.  
  12. /// < /summary> 
  13. /// < remarks>Override this to unhook functionality from the AssociatedObject.< /remarks> 
  14. protected override void OnDetaching()  
  15. {  
  16. this.AssociatedObject.MouseWheel -new MouseWheelEventHandler(AssociatedObject_MouseWheel);  
  17. base.OnDetaching();  

现在行为已经准备好连接到对象,但它没有做任何事情,我们需要为可滚动组件实现滚动。

滚动可滚动的组件 -- 并非如此简单

由于没有通用的滚动接口,即使为ScrollViewer创建一个行为比较简单,但为DataGrid或ListBox创建滚动行为却并不简单。

我在http://blog.thekieners.com/2009/04/06/how-to-enable-mouse-wheel-scrolling-in-silverlight-without-extending-controls/发现有人曾经写过一篇文章介绍如何使用Automation API而不扩展控件实现鼠标滚动。大家可以去了解一下。这里我们需要知道的是Automation API提供了一个IScrollProvider接口,因此我们需要修改OnAttached方法,为连接对象创建Automation Peer。 

  1. /// < summary>   
  2.  /// Gets or sets the peer.  
  3.  /// < /summary> 
  4.  /// < value>The peer.< /value> 
  5.  private AutomationPeer Peer { get; set; }  
  6.  /// < summary> 
  7.  /// Called after the behavior is attached to an AssociatedObject.  
  8.  /// < /summary> 
  9.  /// < remarks>Override this to hook up functionality to the AssociatedObject.< /remarks> 
  10.  protected override void OnAttached()  
  11.  {  
  12.  this.Peer = FrameworkElementAutomationPeer.FromElement(this.AssociatedObject);  
  13.  if (this.Peer == null)  
  14.  this.Peer = FrameworkElementAutomationPeer.CreatePeerForElement(this.AssociatedObject);  
  15.  this.AssociatedObject.MouseWheel += new MouseWheelEventHandler(AssociatedObject_MouseWheel);  
  16.  base.OnAttached();  
  17.  } 

如果控件已经创建了自动化接口,我们首先来研究一下它,如果接口不存在,我们需要先创建,AutomationPeer作为一个成员属性保存,使用MouseWheel事件时会使用到它,下面是滚动目标对象的示例代码:

  1.  /// < summary>   
  2.  /// Handles the MouseWheel event of the AssociatedObject control.  
  3.  /// < /summary> 
  4.  /// < param name="sender">The source of the event.< /param> 
  5.  /// < param name="e">The < see cref="System.Windows.Input.MouseWheelEventArgs"/> instance containing the event data.< /param> 
  6.  void AssociatedObject_MouseWheel(object sender, MouseWheelEventArgs e)  
  7.  {  
  8.  this.AssociatedObject.Focus();  
  9.  int direction = Math.Sign(e.Delta);  
  10.  ScrollAmount scrollAmount =  
  11.  (direction < 0) ? ScrollAmount.SmallIncrement : ScrollAmount.SmallDecrement;  
  12.  if (this.Peer != null)  
  13.  {  
  14.  IScrollProvider scrollProvider =  
  15.  this.Peer.GetPattern(PatternInterface.Scroll) as IScrollProvider;  
  16.  bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;  
  17. if (scrollProvider != null && scrollProvider.VerticallyScrollable && !shiftKey)  
  18.  scrollProvider.Scroll(ScrollAmount.NoAmount, scrollAmount);  
  19.  else if (scrollProvider != null && scrollProvider.VerticallyScrollable && shiftKey)  
  20.  scrollProvider.Scroll(scrollAmount, ScrollAmount.NoAmount);  
  21.  }  
  22.  } 

我们获取了Delta后需要提取出滚动的方向,否则我们就不能指定目标滚动的像素数量,但ScrollAmount可能是SmallIncrement或SmallDecrement(或LargeIncrement,LargeDecrement),因此使用方向我们可以确定是递增还是递减。

由于控件既可以横向滚动也可以纵向滚动,我决定检查换档键是否被按下,如果按下就实现横向滚动,***在IScrollProvider中使用Scroll方法,不需要检查边界。

使用行为

使用Blend应用行为的操作非常简单,Blend资产库会扫描项目中所有的类,并显示出来,因此只需要拖动行为到滚动组件上就可以应用行为了,我们需要学习的是通过编码应用行为,下面是一个例子:   

  1.  < UserControl   
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  3.  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  4.  xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
  5.  xmlns:local="clr-namespace:Elite.Silverlight3.MouseWheelSample.Silverlight.Classes" 
  6.  xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
  7. x:Class="Elite.Silverlight3.MouseWheelSample.Silverlight.MainPage" 
  8.  Width="Auto" Height="Auto"> 
  9.  ... omissis ...  
  10.  < data:DataGrid Grid.Column="" Grid.Row="0" ItemsSource="{Binding DataItems}" Margin="20"> 
  11.  < i:Interaction.Behaviors> 
  12.  < local:MouseWheelScrollBehavior /> 
  13.  < /i:Interaction.Behaviors> 
  14.  < /data:DataGrid> 

在UserControl中,我们声明了要使用的命名空间,在这个例子中,"i"代表交互,"local"指的是融入了新行为的本地类,在第二部分中我们将行为连接到DataGrid了,将行为连接到ScrollViewer或ListBox的代码非常类似,运行这个项目,我们在DataGrid上就可以使用鼠标滚轮了。

Silverlight 3.0 RTW新特性小结

本文介绍的Silverlight 3.0 RTW新特性非常有实用价值,几乎适用于所有的可滚动控件,但ComboBox是个例外,因为它没有直接实现IScrollProvider接口,缺点是只能工作在Windows上,这是一个较大的问题,但目前并没有解决办法,因为它是目前通过编程实现滚动的唯一方法,此外我还注意到MouseWheel事件只能在Windows下IE和Firefox (非Windows模式)中工作,这是由Safari和Firefox 的架构决定的,唯一变通的方法是使用DOM事件。

【编辑推荐】

  1. 微软Silverlight 3挑战Adobe AIR
  2. RIA大战在即 微软Silverlight胜算几何
  3. 图解Silverlight 3的7个新功能
  4. Flash与Silverlight多领域实测对比
  5. 微软宣称Silverlight装机量超过三亿
责任编辑:彭凡 来源: IT专家网
相关推荐

2012-08-28 09:54:35

SilverlightRapidSLSilverlight

2011-07-27 16:12:35

Linux KerneLinux内核

2009-08-27 16:24:48

扩展方法C# 3.0新特性

2010-12-06 09:33:21

Silverlight

2013-07-29 15:13:35

2009-07-08 09:35:53

Java ServleServlet 3.0

2009-12-29 16:21:46

silverlight

2009-08-31 14:45:07

Visual C# 3

2009-06-29 17:42:03

Tapestry5新特

2012-01-09 16:00:56

2010-04-30 09:19:05

Servlet 3.0

2009-08-24 17:55:44

C#3.0新特性

2010-06-23 15:29:52

Eclipse 3.6Java

2011-02-21 16:39:47

Android 2.3Android R5

2010-07-29 09:03:18

Silverlight

2017-11-13 08:44:19

Android Stu移动数据库Kotlin

2021-04-02 10:30:18

Vue3.0前端代码

2010-01-14 09:15:07

Java EE 6Servlet 3.0异步处理

2009-12-30 10:21:36

.NET 4.0

2009-04-08 09:29:34

SQL Server新特性Resource Go
点赞
收藏

51CTO技术栈公众号