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






2.71/5 (4投票s)
在 WPF 中使用 XAML 进度条进行不确定模式
任何应用程序中的长时间运行任务都会导致应用程序或软件无响应。因此,为了让用户了解正在运行的任务,并在长时间运行任务期间保持应用程序的响应性,我们可以使用不同类型的加载条选项,例如:
- Progress Bar
- 环形进度条
等等。
让我们讨论一下 WPF 应用程序中的 XAML 进度条。
- 什么是进度条?
XAML 进度条表示一个控件,用于指示操作正在进行中。它看起来像这样。
XAML 进度条有两种状态:
- 确定模式
- 不确定模式
确定模式
在这种状态下,用户将了解已完成的操作量。
不确定模式
当我们不确定耗时任务的总执行时间时,我们使用这种状态的进度条。请参阅倒数第二张图片以查看其形状。
- 从一个简单的示例开始
打开 Visual Studio 并创建一个空白的 WPF 应用程序
- 单击确定后,您将看到一个空应用程序,如下所示:
- 我们需要三个控件来实现此应用程序中的进度条控件:
- Button
- 进度条
- 文本块
按钮以启动一个耗时任务,一个标签用于显示时间,另一个标签用于显示状态
创建一个 网格 并相应地放置这些控件。
<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();
之后,我们需要两个函数:
- 一个方法将在后台方法响应时调用
- 另一个方法将用于模拟长时间运行的任务,该方法会将第一个方法的引用作为参数传递。
这是第一个方法:
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。