![sample.jpg](http://www.codeproject.com/KB/ajax/MultiTaskIndicator/sample.jpg)
1. 引言
通过Ajax刷新页面,该定制的Web控件用来显示连续的并且耗时长的任务处理进度。
用户在Web窗体上通过点击按钮来实现邮件的群发。为了加强系统的响应性,我想来显示每封邮件的发送进度,然后意识到这个想法也可以应用在很多多任务同时执行的环境中。
2. 实现
我利用Anthem.NET库自定义该控件,使用Anthem.NET库原因有二:一是使用Javascript可以容易 调用服务器端的方法,二是自从我在许多项目中使用后,对Anthem.NET确实比较放心:)。使用该控 件不需要你熟悉Anthem.NET,但是如果你从没有接触过Anthem.NET,我建议你还是了解一下。
为了让该控件完全容易定制,我用GridView控件作为其基类,所以你可以使用任意多的列和自己 所喜欢的风格。
3. 代码使用
由于该控件继承自GridView控件,所以你只能象使用GridView控件一样来使用它,但是还有附加的一些属性、事件和方法需要你掌握。
通过两种方式来显示进度和状态变化:图片和标签。你可以同时使用两种或者其中一种,这两个进度指示器与两个属性(ImageID和LabelID)相对应,这两个属性必须包含Image和Label控件的ID。否则,你要把他们添加进去,如果不想用其中一个属性,尽可忽略之。
为了清楚起见,下面代码说明了该控件如何使用图像指示器。
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![None.gif](/Images/OutliningIndicators/None.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
6
![None.gif](/Images/OutliningIndicators/None.gif)
7
![None.gif](/Images/OutliningIndicators/None.gif)
8
![None.gif](/Images/OutliningIndicators/None.gif)
9
![None.gif](/Images/OutliningIndicators/None.gif)
10
![None.gif](/Images/OutliningIndicators/None.gif)
11
![None.gif](/Images/OutliningIndicators/None.gif)
12
![None.gif](/Images/OutliningIndicators/None.gif)
13
![None.gif](/Images/OutliningIndicators/None.gif)
14
![None.gif](/Images/OutliningIndicators/None.gif)
15
![None.gif](/Images/OutliningIndicators/None.gif)
16
![None.gif](/Images/OutliningIndicators/None.gif)
17
![None.gif](/Images/OutliningIndicators/None.gif)
18
![None.gif](/Images/OutliningIndicators/None.gif)
19
![None.gif](/Images/OutliningIndicators/None.gif)
20
![None.gif](/Images/OutliningIndicators/None.gif)
我们需要注意如下属性:
l ImageID
–对应于设计视图中Image控件的ID值
l ProcessingImageURL
–在任务执行过程中所显示图片的URL路径
l TaskFinishedImageURL
–在任务执行结束后所显示图片的URL路径(该图片可通过编程来实现变化)
l CancelButtonID
–如果窗体中使用取消按钮,应指明该按钮的ID值
![None.gif](/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
3
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
4
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
5
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
7
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
8
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
9
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
10
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
11
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
12
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
13
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
14
![None.gif](/Images/OutliningIndicators/None.gif)
在执行任务前,我们需要把控件与数据源绑定,该数据源包含任意多代表任务的列表。
我们需要调用StartTasks方法来启动该进程。
![None.gif](/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
3
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
4
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
现在我们必须处理ExcuteTask事件以完成所需处理的任务,我们可通过MultiTaskIndicatorEventArgs
的UserData属性
向TaskEnded事件处理器传递一个参数。
![None.gif](/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
3
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
4
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
5
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
7
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
8
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
9
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
10
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
11
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
12
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
13
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
14
![None.gif](/Images/OutliningIndicators/None.gif)
对于基本的功能实现来说,这些已经足够了。但是我们还想根据任务的完成情况来修改其默认的行为。
![None.gif](/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
3
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
4
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
6
![None.gif](/Images/OutliningIndicators/None.gif)
7
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](/Images/dot.gif)
8
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
9
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
10
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
11
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](/Images/dot.gif)
12
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
13
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
14
![ExpandedSubBlockEnd.gif](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
15
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
16
![None.gif](/Images/OutliningIndicators/None.gif)
1. 结语
我希望你会喜欢该控件,并下载把玩之:)。由于我的需求非常简单特殊,所以可能会没有囊括其他一些有意思的特色功能。但是我确信它完全能够灵活定制并重用于大多场合中。