【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
? ? ? ? 软件上面如果一个操作比较缓慢,或者说需要很长的时间,那么这个时候最好添加一个进度条,提示一下当前任务的进展。这就是任务条的主要目的。试想一下,如果我们在下载文件、烧写文件、解压文件的时候,没有进度条提示我们,是不是很容易误认为软件出了什么问题,或者说软件是不是死锁了。而有了一个进度条之后,至少可以提示我们软件还在运行,所有的工作仍在推进当中,只不过进度比较慢而已。
? ? ? ? 本身c# wpf也提供了进度条的控件,使用也不算复杂。需要注意的一点是,在vs2017或者更新一点的编译器上,最好采用异步更新的方法来更新控件的内容。
? ? ? ? 为了演示进度条,首先需要插入进度条控件,其次是label,最后是按钮。当按钮按下去的时候,进度条开始更新,label显示百分比。它的xaml文件是这样的,
<Window x:Class="WpfApp.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:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfApp"
mc:Ignorable="d"
Title="ProgressBarDemo" Height="450" Width="600">
<Grid>
<ProgressBar Name="progressBar" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" Height="20" Margin="20,100"/>
<Label Name="label" Content="0%" HorizontalAlignment="Left" VerticalAlignment="Top" Width="50" Height="30" Margin="20,150,0,0"/>
<Button Content="Start Task" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,200,0,0" Click="StartTask_Click"/>
</Grid>
</Window>
? ? ? ? 如果把xaml文件转换成图形,则是这样的,
? ? ? ? 有了界面之后,下面就可以进行代码的编写。这里面,最重要的实现就是按钮的回调函数。在回调函数中,我们会对进度条进行更新,同时也会对label的内容进行更新。相关的写法,大家最好能够熟练掌握,这样在后续使用的时候,直接拷贝复制即可。
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
using System.Threading.Tasks;
namespace WpfApp
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
// construct function
public MainWindow()
{
InitializeComponent();
}
private async void StartTask_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
int totalSteps = 100;
for (int i = 0; i <= totalSteps; i+=1)
{
UpdateProgressBar(i);
Task.Delay(50).Wait();
}
});
MessageBox.Show("Task finished!");
}
private void UpdateProgressBar(int value)
{
Application.Current.Dispatcher.Invoke(() =>
{
progressBar.Value = value;
label.Content = Convert.ToString(value) + "%";
});
}
}
}
? ? ? ? 代码中最值得说的部分,就是await这个操作。它本身相当于启动了一个thread,await里面的函数内容就是thread的函数体。每次递增的时候,函数体会进一步调用UpdateProgressBar这个子函数,里面包含了控件的更新部分,即Dispatcher.Invoke操作。
? ? ? ? 而StartTask_Click函数会等待这个thread完成,在操作结束之后,会弹出一个消息对话框,告诉用户,当前任务已经完成了。
? ? ? ? 界面和代码都ok之后,接下来就可以开始测试了。首先是编译,编译无误之后,直接单击按钮操作,如果没有什么问题的话,我们就会看到相关的更新和打印,