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

在 WPF 中使用 XAML 进度条进行不确定模式

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.71/5 (4投票s)

2018年1月18日

CPOL

2分钟阅读

viewsIcon

24941

downloadIcon

586

在 WPF 中使用 XAML 进度条进行不确定模式

任何应用程序中的长时间运行任务都会导致应用程序或软件无响应。因此,为了让用户了解正在运行的任务,并在长时间运行任务期间保持应用程序的响应性,我们可以使用不同类型的加载条选项,例如:

  • Progress Bar
  • 环形进度条

等等。

让我们讨论一下 WPF 应用程序中的 XAML 进度条。

  1. 什么是进度条?

    XAML 进度条表示一个控件,用于指示操作正在进行中。它看起来像这样。

    XAML 进度条有两种状态:

    • 确定模式
    • 不确定模式

    确定模式

    在这种状态下,用户将了解已完成的操作量。

                    

    不确定模式

    当我们不确定耗时任务的总执行时间时,我们使用这种状态的进度条。请参阅倒数第二张图片以查看其形状。

                              

  2. 从一个简单的示例开始

    打开 Visual Studio 并创建一个空白的 WPF 应用程序

  3. 单击确定后,您将看到一个空应用程序,如下所示:

  4. 我们需要三个控件来实现此应用程序中的进度条控件:
    1. Button
    2. 进度条
    3. 文本块

按钮以启动一个耗时任务,一个标签用于显示时间,另一个标签用于显示状态

创建一个 网格 并相应地放置这些控件。

<Window x:Class="ProgressBarUndefinedTimeWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ProgressBarUndefinedTimeWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        
       <Button Grid.Row="1" x:Name="btn_StartLengthyTask" Click="btn_StartLengthyTask_Click" Width="200" Height="30" >Start Lengthy Task</Button>
        <ProgressBar Grid.Row="2" x:Name="pb_LengthyTaskProgress" Margin="10,20"  Value="10" ></ProgressBar>
        <TextBlock Grid.Row="3" x:Name="lbl_TaskStatus" >Status...</TextBlock>
    </Grid>
</Window>

现在我们需要理解一种称为 事件驱动模型 的编程模型。因为我们将启动一个后台任务,并且不知道该任务的完成时间。每当该任务完成处理时,它将在 UI 线程上调用一个函数,以告知用户任务已完成。并且该函数引用将在调用它时作为参数传递给后台线程。

因此,为了保存函数引用,我们使用 委托。该委托将包含 UI 函数的引用,并将其作为参数传递给后台工作函数。

所以首先,我们将在程序中声明一个委托,如下所示:

请记住,我们在命名空间而不是类中声明委托。并在类中使用它们

              

这是代码

public delegate void RefToFunction();

之后,我们需要两个函数:

  1. 一个方法将在后台方法响应时调用
  2. 另一个方法将用于模拟长时间运行的任务,该方法会将第一个方法的引用作为参数传递。

这是第一个方法:

private async Task PerformLengthyTaskAsync(RefToFunction toFunction)
        {
            for (int i = 0; i < 5; i++) // 5 sec task
            {
                await Task.Delay(1000); // wait for 1 sec
            }
            toFunction.Invoke();
        }

这是第二个方法:

private void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
        {
            lbl_TaskStatus.Text = "Task in progress...";
            pb_LengthyTaskProgress.IsIndeterminate = true;

            RefToFunction toFunction = new RefToFunction(OnReponse);

            PerformLengthyTaskAsync(toFunction);
        }

我们将从按钮单击事件的代码背后调用第二个方法。

private void btn_StartLengthyTask_Click(object sender, RoutedEventArgs e)
        {
            lbl_TaskStatus.Text = "Task in progress...";
            pb_LengthyTaskProgress.IsIndeterminate = true;

            RefToFunction toFunction = new RefToFunction(OnReponse);

            PerformLengthyTaskAsync(toFunction);
        }

您需要使用以下命名空间才能使用 Tasks:

using System.Threading.Tasks;

构建项目并运行它。单击按钮后,进度条将显示 5 秒钟。任务完成后,第二个方法将触发 OnReponse 方法。我们可以在那里相应地更改 UI。

                 

© . All rights reserved.