一、开篇废话和牢骚
从 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,打完收工。