WPF 进度条
这是一个在 WPF 中使用进度条的简单示例。
引言
本文演示了如何在“紧密代码循环”中使用 WPF ProgressBar
。
背景
多年来,进度条在常规 Windows Forms 应用程序中非常有用且易于使用。 所需的只是设置 Minimum
和 Maximum
属性,然后逐步修改 Value
属性以报告进度。 在必要时,会插入 DoEvents()
以允许表单刷新并更新进度条。
WPF 进度条在概念上与 Windows 进度条相同; 但是,一个非常明显的区别是,使用标准的编码技术,WPF 进度条在应用程序处理时无法正确更新。 这会产生非常不良的效果,尤其是因为进度条的全部目的是...报告进度。
在代码中需要“紧密循环”的情况有很多,例如从文件中读取数据时。 一种标准的编码方法是打开文件,然后循环遍历整个文件,每次读取行、字符或字节。 可以使用进度条来报告此操作的进度。
紧密循环给 WPF 进度条带来了一些挑战,并且标准的编码技术不会产生与 Windows Forms 相同的结果。 因此,本文专门解决了这个问题,并演示了如何在“紧密代码循环”中使用 WPF ProgressBar
。
使用代码
WPF ProgressBar
具有一个“SetValue
”方法,可用于更新 ProgressBar
的进度。 但是,此方法不会在存在紧密编码循环时导致 ProgresssBar
刷新。 因此,有必要使用 Dispatcher
类的 Invoke
方法来更新 ProgressBar
的进度,并使其在表单上正确刷新。
Dispatcher
类提供用于管理线程的工作项队列的服务。
Dispatcher.Invoke
方法的参数之一是委托。 由于可以创建委托并用于指向要调用的特定方法,因此我们将创建一个委托并将其用于指向 ProgressBar
的 SetValue
方法,以便它具有完全相同的签名。
这是 Visual Basic 和 C# 中的完整示例
Visual Basic
'Create a Delegate that matches
'the Signature of the ProgressBar's SetValue method
Private Delegate Sub UpdateProgressBarDelegate(ByVal dp As _
System.Windows.DependencyProperty, _
ByVal value As Object)
Private Sub Process()
'Configure the ProgressBar
ProgressBar1.Minimum = 0
ProgressBar1.Maximum = Short.MaxValue
ProgressBar1.Value = 0
'Stores the value of the ProgressBar
Dim value As Double = 0
'Create a new instance of our ProgressBar Delegate that points
' to the ProgressBar's SetValue method.
Dim updatePbDelegate As New _
UpdateProgressBarDelegate(AddressOf ProgressBar1.SetValue)
'Tight Loop: Loop until the ProgressBar.Value reaches the max
Do Until ProgressBar1.Value = ProgressBar1.Maximum
value += 1
'Update the Value of the ProgressBar:
' 1) Pass the "updatePbDelegate" delegate
' that points to the ProgressBar1.SetValue method
' 2) Set the DispatcherPriority to "Background"
' 3) Pass an Object() Array containing the property
' to update (ProgressBar.ValueProperty) and the new value
Dispatcher.Invoke(updatePbDelegate, _
System.Windows.Threading.DispatcherPriority.Background, _
New Object() {ProgressBar.ValueProperty, value})
Loop
End Sub
C#
//Create a Delegate that matches
//the Signature of the ProgressBar's SetValue method
private delegate void UpdateProgressBarDelegate(
System.Windows.DependencyProperty dp, Object value);
private void Process()
{
//Configure the ProgressBar
ProgressBar1.Minimum = 0;
ProgressBar1.Maximum = short.MaxValue;
ProgressBar1.Value = 0;
//Stores the value of the ProgressBar
double value = 0;
//Create a new instance of our ProgressBar Delegate that points
// to the ProgressBar's SetValue method.
UpdateProgressBarDelegate updatePbDelegate =
new UpdateProgressBarDelegate(ProgressBar1.SetValue);
//Tight Loop: Loop until the ProgressBar.Value reaches the max
do
{
value += 1;
/*Update the Value of the ProgressBar:
1) Pass the "updatePbDelegate" delegate
that points to the ProgressBar1.SetValue method
2) Set the DispatcherPriority to "Background"
3) Pass an Object() Array containing the property
to update (ProgressBar.ValueProperty) and the new value */
Dispatcher.Invoke(updatePbDelegate,
System.Windows.Threading.DispatcherPriority.Background,
new object[] { ProgressBar.ValueProperty, value });
}
while (ProgressBar1.Value != ProgressBar1.Maximum);
}
结论
这是一篇非常简短、希望清晰简洁的文章,介绍了如何使用 WPF ProgressBar
。 为了方便您参考,其中包含 Visual Basic 和 C# 的源代码。
希望对您有所帮助!