一、开篇废话和牢骚
从 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一下,
item 类型:System.Object 要滚动到的数据项(行)。
column 类型:System.Windows.Controls.DataGridColumn 要滚动到的列。
后悔啊,小学语文没学好,楞是没看明白怎么用。
继续寻找,功夫不负有心人,终于在 silverlight.net 的论坛上找到了一个例子,下载,实践,每次只滚一下,第二次就不响应,失败。不过他却给出一个很重要的内容,如何调用 ScrollIntoView 。呵呵,修改一下,然后又从 DXperience的AgDataGrid代码中偷了关于响应MouseWheel的Helper终于完整的搞定这个问题了。
代码如下:
1.先写一个MouseHelper.cs用来帮助我们处理MouseWheel
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控件。
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,打完收工。