展示一个鼠标滚动事件的示例只需要几行代码即可,我认为大部分人都可以在几分钟内做好,并理解它是如何工作的。因此我决定将这个事件和Expression Blend中引入的新行为一起合并成一个例子进行介绍,本文主要介绍如何创建行为,如何使用鼠标滚动事件,以及如何将其添加到可滚动的控件上,以便使用鼠标滚轮。
行为是什么?
你可能曾经在ASP.NET Ajax框架中使用过行为,说得简单点这里的行为就是ASP.NET Ajax语法的Silverlight实现,允许创建可复用的和可连接到HTML控件的行为。(让Silverlight 3操作简单的和手工具)
从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: // 在这里添加实现代码
4: }
由于我们是要扩展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:
11: /// < summary>
12: /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
13: /// < /summary>
14: /// < remarks>Override this to unhook functionality from the AssociatedObject.< /remarks>
15: protected override void OnDetaching()
16: {
17: this.AssociatedObject.MouseWheel -= new MouseWheelEventHandler(AssociatedObject_MouseWheel);
18: base.OnDetaching();
19: }
现在行为已经准备好连接到对象,但它没有做任何事情,我们需要为可滚动组件实现滚动。
滚动可滚动的组件 -- 并非如此简单
由于没有通用的滚动接口,即使为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:
7: /// < summary>
8: /// Called after the behavior is attached to an AssociatedObject.
9: /// < /summary>
10: /// < remarks>Override this to hook up functionality to the AssociatedObject.< /remarks>
11: protected override void OnAttached()
12: {
13: this.Peer = FrameworkElementAutomationPeer.FromElement(this.AssociatedObject);
14:
15: if (this.Peer == null)
16: this.Peer = FrameworkElementAutomationPeer.CreatePeerForElement(this.AssociatedObject);
17:
18: this.AssociatedObject.MouseWheel += new MouseWheelEventHandler(AssociatedObject_MouseWheel);
19: base.OnAttached();
20: }
如果控件已经创建了自动化接口,我们首先来研究一下它,如果接口不存在,我们需要先创建,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:
10: int direction = Math.Sign(e.Delta);
11:
12: ScrollAmount scrollAmount =
13: (direction < 0) ? ScrollAmount.SmallIncrement : ScrollAmount.SmallDecrement;
14:
15: if (this.Peer != null)
16: {
17: IScrollProvider scrollProvider =
18: this.Peer.GetPattern(PatternInterface.Scroll) as IScrollProvider;
19:
20: bool shiftKey = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
21:
22: if (scrollProvider != null && scrollProvider.VerticallyScrollable && !shiftKey)
23: scrollProvider.Scroll(ScrollAmount.NoAmount, scrollAmount);
24: else if (scrollProvider != null && scrollProvider.VerticallyScrollable && shiftKey)
25: scrollProvider.Scroll(scrollAmount, ScrollAmount.NoAmount);
26: }
27: }
我们获取了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:
10: ... omissis ...
11:
12: < data:DataGrid Grid.Column="1" Grid.Row="0" ItemsSource="{Binding DataItems}" Margin="20">
13: < i:Interaction.Behaviors>
14: < local:MouseWheelScrollBehavior />
15: < /i:Interaction.Behaviors>
16: < /data:DataGrid>
在UserControl中,我们声明了要使用的命名空间,在这个例子中,"i"代表交互,"local"指的是融入了新行为的本地类,在第二部分中我们将行为连接到DataGrid了,将行为连接到ScrollViewer或ListBox的代码非常类似,运行这个项目,我们在DataGrid上就可以使用鼠标滚轮了。
小结
本文介绍的技术非常有实用价值,几乎适用于所有的可滚动控件,但ComboBox是个例外,因为它没有直接实现IScrollProvider接口,缺点是只能工作在Windows上,这是一个较大的问题,但目前并没有解决办法,因为它是目前通过编程实现滚动的唯一方法,此外我还注意到MouseWheel事件只能在Windows下IE和Firefox (非Windows模式)中工作,这是由Safari和Firefox 的架构决定的,唯一变通的方法是使用DOM事件。

Silverlight 3.0 RTW引入-- 鼠标滚动事件相关推荐

  1. 鼠标滚动事件,鼠标滚动一下,屏幕滑动一屏

    思路:1.判断鼠标向上还是向下滚动 2.执行鼠标事件 鼠标滚动事件注册事件资料:https://www.cnblogs.com/wsoft/articles/2856861.html <!DOC ...

  2. 在FireFox浏览器上,用stopImmediatePropagation阻止冒泡鼠标滚动事件

    楔子 是不是在火狐用stopPropagation不太满意 很久没有笑过又不知为何 既然不快乐又不喜欢这里 不如一路向西用stopImmediatePropagation(其实我对浏览器的兼容性看不顺 ...

  3. Vue 鼠标滚动事件

    在最外层标签添加 :@wheel 鼠标滚动事件 <template :@wheel="closeSelect"> 在mounted中挂载 监听鼠标滚动事件的方法 mou ...

  4. css 鼠标滚动事件,js监听鼠标的滚轮滚动事件教程

    不同的有不同的滚轮事件.主要是有两种,onmousewheel(firefox不支持)和dommousescroll(只有firefox支持),关于这两个事件这里不做详述,想要了解的朋友请移步:鼠标滚 ...

  5. 关于viewer.js插件js版鼠标滚动事件放大缩小改为图片移动

    主要是为了记录下需求中解决问题的思路,本人前端相当糟糕. 问题的产生是由于图片太长,页面一次性展示不全,业务人员提出修改前端图片显示中的鼠标滚动改为上下移动.由于项目中图片展示使用的是viewer,j ...

  6. 解决ScrollViewer嵌套的DataGrid、ListBox等控件的鼠标滚动事件无效

    C# 中,两个ScrollViewer嵌套在一起或者ScrollViewer里面嵌套一个DataGrid.ListBox.Listview(控件本身有scrollviewer)的时候,我们本想要的效果 ...

  7. vue 鼠标滚动事件 滚动方向

    @wheel.prevent="scrollBarWheel" scrollBarWheel(e) {if (this.synchronizationVar === 1) {e = ...

  8. Silverlight 2.0 RTW 正式版发布(附下载地址)!

    Microsoft Silverlight 2今天终于向用户发布使用. Microsoft Silverlight是一个跨浏览器的.跨平台的插件,为网络带来下一代基于.NET的媒体体验和丰富的交互式应 ...

  9. tkinter绑定鼠标滚轮滚动事件

    大部分的讲python tkinter的书籍好像不太提到如何绑定鼠标滚轮滚动事件哦(其实我也只看了2本书而已).这在某些地方也可能会用到,比如放大缩小图片的时候.我查了下python tkinter文 ...

最新文章

  1. android开发我的新浪微博客户端-登录页面功能篇(4.2)
  2. MapGuide应用开发系列(五)---- Autodesk MapGuide Studio应用简介
  3. Linux下socket最大连接数 ulimit -n 最大值修改
  4. 调用GOOGLE语音
  5. mysql优化varchar索引_MySQL优化--概述以及索引优化分析
  6. html5 打包ios.上架,iOS帮客户打包App上架的正确姿势
  7. vue element form 默认校验
  8. iOS_SN_深浅拷贝( 百度的)_转载
  9. 罗技鼠标驱动G HUB导致触摸板无法使用
  10. JavaScript算术运算中前加加与后加加
  11. office2007中把文件转换成pdf格式的问题
  12. bim软件32位计算机条件,哪些bim软件能在在win732位上运行?
  13. 记一次跟突破360主机卫士上传
  14. 免费学python的网课-像玩游戏一样学Python,和各种网课说再见
  15. 软件工程-软件开发的工程思维
  16. 使用AlphaFold2进行蛋白质结构预测
  17. 小程序引入字体集方式
  18. 【学浪下载教程】02学浪下载之Fiddler学浪插件配置
  19. AndroidStudio4.1 不报错,不爆红
  20. Windows下谨慎使用动态磁盘

热门文章

  1. 超好看的B站首页顶部景深动态特效源码
  2. [转]版本控制软件Subversion的使用笔记(WIN)
  3. 对 app_offline.htm 的几点错误认识
  4. css hacks (ie6,ie7,ie8,firefox,Chrome)
  5. 爬虫入门五(Phantomjs和selenium)
  6. go标准库:time
  7. AIDE --Linux高级入侵检测
  8. 华为机试——求int型正整数在内存中存储时1的个数
  9. Linux sed命令完全攻略(超级详细)
  10. Linux tail命令:显示文件结尾的内容