现在的位置: 首页 > 综合 > 正文

Silverlight学习笔记一:DataGrid如何处理鼠标的滚轮事件

2012年05月02日 ⁄ 综合 ⁄ 共 5931字 ⁄ 字号 评论关闭

一、开篇废话和牢骚
    从 Silverlight 1 就开始对它敢兴趣了,不过一直都没有认真看过,更没有实践过。2.0出来之后,终于有了试验一下的念头,可惜,在安装 Silverlight 时却出现了问题,总是提示 vs2008 的 sp1 没有安装,可是我明明安装了啊,baidu、google了一下,没有找到任何有意义的解决方案。最终放弃了。不过上周,由于在编译 DXperience 8.32 的源代码出现问题,一怒之下,把 vm 里的 xp 重装了一边,搞定 DXperience 之后,突然想起了 Silverlight ,决定再试一次,竟然安装上。哈哈。终于可以开始我的 Silverlight 学习之旅了。
    从本周一开始正式学习,上午先看了看网上各位高手的教学,简单的做了页面,一个字,爽啊。可惜下午峰回路转,在开始准备做一个像点样子的例子的时候,发现问题一大堆。发现要用 Silverlight ,除了 Silverlight 本身之外,还有一坨东西 WCF 、 Linq 、Linq To SQL、ADO NET Entity Data Model 、 ADO.NET 数据服务。。。。我晕,这些东西,我都只是听说过,没有一个真正学过。唉,这么会有这么多的新东西啊,看样子我是过时了。哈哈。慢慢看吧。
    在学习用Grid等布局之后,做好了页头和左边的导航栏,这是出现了第一个问题,就是导航,在WEB上,我们用框架很容易做到,可是在 Silverlight 上怎么实现呢,我怎么让我的其它页面嵌入的右边的区域呢。这个问题现在看来很弱智,但是对应刚学 Silverlight 的我来说去很困难,看了看 Silverlight 帮助中的关于导航的介绍,没看明白。然后 baidu、google,呵呵,没有发现有人介绍的,更晕的是,很多的例子好像都是只有一个页面,不需要导航,可是真正的项目不可能只有一个页面啊,可是为什么没有人介绍啊?我想应该是这个问题太简单了,根本就需要介绍,可是我不是高手啊,没办法。自己找代码看吧。先看了一下 Silverlight Toolkit 的 Samples 代码,他的页面就是我要的那种效果,打开 SampleBrowser.cs 看,可惜对于才学半天 Silverlight 的我来说,一下子没看明白,放弃,又找来了 Silverlight Controls Demo 的代码,哈哈,还是这个好,简简单单,我喜欢,原来就是在 panel 的 children add就可以了,呵呵,第一问题搞定。
    这里要发发牢骚,就是发现很多高手们写的文章很好,可是大部分都是理论有余,实践不足,介绍了很多理论知识,而在举例子的时候,又回避了很多在实际开发中会遇到的很多很细节性的问题,虽然这些问题往往很简单,但是对应新手来说,却很复杂。所以我决定把我学习中碰到的各种小问题记录下来,供新手们参考。
    另外,我是一个快餐主义者,喜欢快速简单的解决问题,很少关注深层次的东西,所以我所介绍的解决方案,应该都不是最好的解决方案,有的可能还是错误的,但是,这些方案都可以帮你解决一部分的问题,或者提供一些思路,所以有错误的地方请大家见谅。

二、DataGrid中如何处理鼠标的滚轮(MouseWheel)
    这是我遇到的第二个问题,我写了个页面,用DataGrid显示了Northwind中Products表的数据,应为数据比较多,DataGrid出现了垂直滚动条,但是,我们却没有办法用鼠标滚轮来滚动数据。
    其实看到这个问题的时候真的很晕,不知道微软是不是脑子进水了,Silverlight 都到2.0了居然还不支持滚轮,实在搞不明白为什么。
既然他不知道,那就自己搞定把,再次 baidu、google,呵呵,一大堆的方案,窃喜,以为这个问题很快就能搞定呢。可是仔细一看,晕,居然都是介绍如何响应 MouseWheel 的,但是就是没有一个介绍在获取了事件之后,如果处理 DataGrid 。自己搞定把,看看了 DataGrid 的方法,里面有一个 ScrollIntoView 的方法,Help一下,

public void ScrollIntoView(Object item, DataGridColumn column)

参数
    item 类型:System.Object 要滚动到的数据项(行)。
    column 类型:System.Windows.Controls.DataGridColumn 要滚动到的列。

    后悔啊,小学语文没学好,楞是没看明白怎么用。
    继续寻找,功夫不负有心人,终于在 silverlight.net 的论坛上找到了一个例子,下载,实践,每次只滚一下,第二次就不响应,失败。不过他却给出一个很重要的内容,如何调用 ScrollIntoView 。呵呵,修改一下,然后又从 DXperience的AgDataGrid代码中偷了关于响应MouseWheel的Helper终于完整的搞定这个问题了。
代码如下:
1.先写一个MouseHelper.cs用来帮助我们处理MouseWheel

 1 namespace SilverlightDemoApp
 2  {
 3      public delegate void MouseWheelEventHandler(object sender, MouseWheelHandlerEventArgs e);
 4      public class MouseWheelHandlerEventArgs : EventArgs
 5      {
 6          double delta;
 7          public MouseWheelHandlerEventArgs() : this(0) { }
 8          public MouseWheelHandlerEventArgs(double delta)
 9          {
10              this.delta = delta;
11          }
12          public double Delta { get { return delta; } }
13      }
14      internal static class MouseHelper
15      {
16          static List<MouseWheelEventHandler> wheelHandler = new List<MouseWheelEventHandler>();
17          public static void SetMouseWheelHandler(MouseWheelEventHandler _wheelHandler)
18          {
19              wheelHandler.Add(_wheelHandler);
20              if (HtmlPage.IsEnabled && HtmlPage.Window != null)
21              {
22                  HtmlPage.Window.AttachEvent("DOMMouseScroll", OnMouseWheelTurned);
23                  HtmlPage.Window.AttachEvent("onmousewheel", OnMouseWheelTurned);
24                  HtmlPage.Document.AttachEvent("onmousewheel", OnMouseWheelTurned);
25              }
26          }
27          static void OnMouseWheelTurned(Object sender, HtmlEventArgs args)
28          {
29              double delta = 0;
30              ScriptObject eventObj = args.EventObject;
31              if (eventObj.GetProperty("wheelDelta"!= null)
32              {
33                  delta = ((double)eventObj.GetProperty("wheelDelta")) / 120;
34                  if (HtmlPage.Window.GetProperty("opera"!= null)
35                      delta = -delta;
36              }
37              else if (eventObj.GetProperty("detail"!= null)
38              {
39                  delta = -((double)eventObj.GetProperty("detail")) / 3;
40                  if (HtmlPage.BrowserInformation.UserAgent.IndexOf("Macintosh"!= -1)
41                      delta = delta * 3;
42              }
43              if (delta != 0)
44              {
45                  args.PreventDefault();
46                  eventObj.SetProperty("returnValue"false);
47              }
48              foreach (MouseWheelEventHandler handler in wheelHandler)
49              {
50                  handler(nullnew MouseWheelHandlerEventArgs(delta));
51              }
52          }
53      }
54  }

 

2.DataGrid所在的窗体,上面放上一个DataGrid控件。

 1 public partial class NorthWind : UserControl
 2  {
 3          //DataGrid的数据
 4          private List<Products> _product;
 5          //标示数据是否在DataGrid上
 6          private bool IsMouseInControl { getset; }
 7 
 8         public NorthWind()
 9          {
10              InitializeComponent();
11              //处理MouseWheel
12              MouseHelper.SetMouseWheelHandler(OnMouseWheel);
13              BindGrid();
14          }
15 
16         private void BindGrid()
17          {
18             //DataGrid 绑定数据
19             //从WCF中获取Products数据,并保存到_product中。
20             //以下代码省略
21           }
22 
23         public void OnMouseWheel(object sender, MouseWheelHandlerEventArgs args)
24          {
25              //如果鼠标不在DataGrid上,就不做处理
26              if (!IsMouseInControl) return;
27              int mouseDelta = Math.Sign(args.Delta);
28              var selectedItem = dgData.SelectedIndex;
29              //每次向下滚动一条记录
30              var nextRow = selectedItem - (int)mouseDelta * 1;
31              if (nextRow > -1 && nextRow < _product.Count)
32              {
33                  dgData.ScrollIntoView(_product[nextRow], null);
34                  dgData.SelectedIndex = nextRow;
35              }
36          }
37 
38         private void dgData_MouseEnter(object sender, MouseEventArgs e)
39          {
40              //鼠标进入DataGrid
41              IsMouseInControl = true;
42          }
43 
44         private void dgData_MouseLeave(object sender, MouseEventArgs e)
45          {
46              //鼠标离开DataGrid
47              IsMouseInControl = false;
48          }
49     }

 

ok,打完收工。

 

抱歉!评论已关闭.