精确控制行的拖动行为
为了便于学习本节的内容,可以先打开CaseStudy目录下的文件“ListView.Table”,并参考该文件名为“示例二十二”的窗口。
ListView有个名为“BeforeDropRow”事件,在准备接收拖动过来的行之前触发,这个事件很重要,可以对拖动行为进行精确控制。
BeforeDropRow的e参数有:
Form: 返回触发事件的窗口
Sender: 返回触发事件的控件,也就是准备接收行的ListView
Source: 返回拖动过来的行原来所属的ListView,如果在同一个ListView之间拖动,那么Source就等于Sender
Add: 逻辑型,是否接收拖动过来的行,默认为True,只有在不同的ListView之间拖动时,此参数有意义。
Delete: 逻辑型,是否从原来的ListView删除拖动过来的行,默认为True,只有在不同的ListView之间拖动时,此参数有意义。
OldIndex: 拖动过来的行的原位置。
NewIndex: 新位置,将在此处接收拖动过来的行。
Cancel: 逻辑型,是否取消本次拖动,当然默认为False。
下来用们用一个例子来演示这个事件的用法,任务是设计一个下图所示的窗口:
通过这个窗口,可以以可视化的形式选择或删除活动参与者,也可以活动参与者从一个活动拖到另一个活动,单击保存按钮后,将结果保存在下表中:
设计步骤:
1、窗口的AfterLoad事件代码设置为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
Dim
lvw1
As
WinForm.ListView
=
e.Form.Controls("ListView1")
'员工列表 |
上面的代码中,我首先请你留意第4行到第11行的代码,当我们需要对一组控件进行相同的设置时,可以用这种方法减少代码量;其次留意第15行代码,此行代码将员工列表(ListView1)中的行的Name属性设置为对应员工的姓名,这样我们可以在28、37这两行代码通过员工姓名获取ListView1中这个员工对应的行,然后获取此行的ImageKey属性,并赋值给活动参与者(ListView2和ListView3)中对应行的ImageKey属性。
2、ListView2(活动一参与者)的BeforeDropRow事件代码设置为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Dim
lvw As
WinForm.ListView
= e.Sender |
首先留意第7行代码,意思是如果是从员工列表拖动过来的,那么就不需要删除原来的行;这里隐藏了另一个意思:
如果是从活动二参与者拖动过来的行,那么就原来的行就删除;也就是说,从员工列表拖动员工到活动参与者,是复制的动作,而从一个活动参与者列表拖动员工到另一个活动参与者,是移动的动作;这个看似复杂的判断,就这么三行代码搞定了。
其次请留意第11行的代码是如何判断某员工已经参与此项活动的,这就是行有Name属性的好处,当然你可以遍历判断,但是要多写几行代码。
3、ListView3(活动而参与者)的BeforeDropRow事件代码和ListView2完全相同,就不重复说明了。
4、最后将ListView1(员工列表)的BeforeDropRow事件设置为:
e.Add = False
这简单的一行代码的意思是:从活动参与者拖动员工回到员工列表时,会将此员工从活动参与者列表中删除,但不会在员工列表中再增加此员工,是一种直接删除的动作。
到这里我们总结一些,这一个例子用拖动实现了三种操作:
1、复制,从员工列表拖动员工到活动参与者列表
2、删除,从活动参与者列表拖动员工回员工列表
3、移动,从一个活动参与者列表拖动员工到另一个活动参与者列表
此外还进行了一些条件判断,例如每项活动最多允许3人参加,防止重复报名等。