用此方法。
整个进程是同步进行的,即对窗体进行调用时辅助线程将停止。尽管可以在显示错误消息或完成消息时停止辅助线程,但我们并不希望显示每个小状态时都停止辅助线程。
为了避免显示状态时停止辅助线程,Display 方法将使用 BeginInvoke,而不使用 Invoke。BeginInvoke 使窗体上的方法调用异步进行,这样辅助线程可以一直保持运行状态,不需要等待窗体上的显示方法完成:
Dim disp As New DisplayDelegate( _
AddressOf CType(mClient, IClient).Display)
Dim ar() As Object = {Text}
'' 调用 UI 线程上的客户端窗体
'' 以更新显示
mClient.BeginInvoke(disp, ar)
以这种方式使用 BeginInvoke 可以防止辅助线程停止,使辅助线程具有尽可能高的性能。
ActivityBar 控件
最后,我们来创建显示动画点的 ActivityBar 控件。
在名为 ActivityBar 的项目中添加一个用户控件。
将该控件的宽度调整为约 110,高度调整为约 20。可以通过拖动边界进行调整,也可以通过在 Properties(属性)窗口中设置 Size 属性进行调整。
其余的操作将通过代码完成。要创建一系列在显示时不停闪烁的动画“灯”,可以使用带有 Timer 控件的一系列 PictureBox 控件。每次 Timer 控件关闭时,我们将使下一个 PictureBox 呈绿色显示,并将已经呈绿色显示的 PictureBox 更改为窗体的背景色。
将 Windows Forms(Windows 窗体)选项卡中的 Timer 控件放入窗体中,然后将其名称更改为 tmAnim。同时将 Interval 属性设置为 300,以获得较好的动画速度。
顺便说一句,Components(组件)选项卡中有一个不同的 Timer 控件。它是一个多线程计时器。也就是说,该计时器将在后台线程中引发 Elapsed 事件,而不是象 Windows 窗体计时器那样在 UI 线程上引发 Elapsed 事件。建立 UI 时这种方法通常会产生相反的效果,因为 Elapsed 事件中的代码显然不能直接与我们的 UI 进行交互。
现在,在控件中添加以下代码:
Private mBoxes As New ArrayList()
Private mCount As Integer
Private Sub ActivityBar_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim index As Integer
If mBoxes.Count = 0 Then
For index = 0 To 6
mBoxes.Add(CreateBox(index))
Next
End If
mCount = 0
End Sub
Private Function CreateBox(ByVal index As Integer) As PictureBox
Dim box As New PictureBox()
With box
SetPosition(box, index)
.BorderStyle = BorderStyle.Fixed3D
.Parent = Me
.Visible = True
End With
Return box
End Function
Private Sub GrayDisplay()
Dim index As Integer
For index = 0 To 6
CType(mBoxes(index), PictureBox).BackColor = Me.BackColor
Next
&nbs