65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 进度条

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (47投票s)

2009年7月28日

CPOL

2分钟阅读

viewsIcon

352391

downloadIcon

17114

这是一个在 WPF 中使用进度条的简单示例。

引言

本文演示了如何在“紧密代码循环”中使用 WPF ProgressBar

背景

多年来,进度条在常规 Windows Forms 应用程序中非常有用且易于使用。 所需的只是设置 MinimumMaximum 属性,然后逐步修改 Value 属性以报告进度。 在必要时,会插入 DoEvents() 以允许表单刷新并更新进度条。

WPF 进度条在概念上与 Windows 进度条相同; 但是,一个非常明显的区别是,使用标准的编码技术,WPF 进度条在应用程序处理时无法正确更新。 这会产生非常不良的效果,尤其是因为进度条的全部目的是...报告进度。

在代码中需要“紧密循环”的情况有很多,例如从文件中读取数据时。 一种标准的编码方法是打开文件,然后循环遍历整个文件,每次读取行、字符或字节。 可以使用进度条来报告此操作的进度。

紧密循环给 WPF 进度条带来了一些挑战,并且标准的编码技术不会产生与 Windows Forms 相同的结果。 因此,本文专门解决了这个问题,并演示了如何在“紧密代码循环”中使用 WPF ProgressBar

使用代码

WPF ProgressBar 具有一个“SetValue”方法,可用于更新 ProgressBar 的进度。 但是,此方法不会在存在紧密编码循环时导致 ProgresssBar 刷新。 因此,有必要使用 Dispatcher 类的 Invoke 方法来更新 ProgressBar 的进度,并使其在表单上正确刷新。

Dispatcher 类提供用于管理线程的工作项队列的服务。

Dispatcher.Invoke 方法的参数之一是委托。 由于可以创建委托并用于指向要调用的特定方法,因此我们将创建一个委托并将其用于指向 ProgressBarSetValue 方法,以便它具有完全相同的签名。

这是 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# 的源代码。

希望对您有所帮助!

© . All rights reserved.