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

一、开篇废话和牢骚
    从 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( null new  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 {  get set ; }
 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,打完收工。

 

你可能感兴趣的:(silverlight)