進(jìn)度條常用在加載,下載,導(dǎo)出一些比較耗時(shí)的地方,利用進(jìn)度條能讓用戶看到實(shí)時(shí)進(jìn)展,能有更好的用戶體驗(yàn)……
直接開始
新建一個(gè)wpf項(xiàng)目,然后在主窗口添加一個(gè)按鈕,用來控制進(jìn)度的開始。加一個(gè)進(jìn)度條控件progressbar。雙擊按鈕,為按鈕添加事件,代碼直接循環(huán)模仿進(jìn)度的進(jìn)行……
private void button4_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
//當(dāng)前進(jìn)度,最大值默認(rèn)100
progressBar1.Value = i;
Thread.Sleep(10);
}
}
最簡(jiǎn)單的進(jìn)度條已經(jīng)完成,好的,這里運(yùn)行程序執(zhí)行,你會(huì)發(fā)現(xiàn)一個(gè)問題,點(diǎn)開始之后,界面直接卡住,回過神來,進(jìn)度條已經(jīng)滿了,這和我們想像有點(diǎn)也不一樣啊。你在ui線程里面執(zhí)行了耗時(shí)的操作,就會(huì)讓界面進(jìn)入假死狀態(tài),這時(shí)候我們就要改進(jìn)一下,使用多線程。

多線程開始
我們重新開啟一個(gè)線程來模仿進(jìn)度條進(jìn)度,在按鈕的點(diǎn)擊事件下進(jìn)行調(diào)用。好了,這次在點(diǎn)擊按鈕,我們可以看到進(jìn)度條正常的顯示進(jìn)度情況了,不錯(cuò),不錯(cuò),是這種效果。
private void ProgressBegin()
{
Thread thread = new Thread(new ThreadStart(() =>
{
for (int i = 0; i <= 100; i++)
{
this.progressBar1.Dispatcher.BeginInvoke((ThreadStart)delegate{ this.progressBar1.Value = i; });
Thread.Sleep(100);
}
}));
thread.Start();
}
新窗口來一個(gè)
這個(gè)寫法是一樣的,只不過在新窗口弄一個(gè),用彈窗的方式來顯示,有時(shí)候還是會(huì)用到的。新建一個(gè)wpf窗口,同樣加入一個(gè)進(jìn)度條控件,在主窗口的按鈕點(diǎn)擊事件中寫入新窗口的創(chuàng)建和顯示,在新窗口的構(gòu)造函數(shù)中調(diào)用,進(jìn)度條開始進(jìn)度的方法。
//window1.xaml
<Window x:Class="progressbartest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="217" Width="300">
<Grid>
<ProgressBar Height="24" HorizontalAlignment="Left" Margin="12,72,0,0" Name="progressBar1" VerticalAlignment="Top" Width="254" Foreground="#FF2EAFF1" />
</Grid>
</Window>
//window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
namespace progressbartest
{
/// <summary>
/// Window1.xaml 的交互邏輯
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
ProgressBegin();
}
private void ProgressBegin()
{
Thread thread = new Thread(new ThreadStart(() =>
{
for (int i = 0; i <= 100; i++)
{
this.progressBar1.Dispatcher.BeginInvoke((ThreadStart)delegate { this.progressBar1.Value = i; });
Thread.Sleep(100);
}
}));
thread.Start();
}
}
}

BackgroundWork方式
BackgroundWorker類允許您在單獨(dú)的線程上執(zhí)行某個(gè)可能導(dǎo)致用戶界面(UI)停止響應(yīng)的耗時(shí)操作(比如文件下載數(shù)據(jù)庫事務(wù)等),并且想要一個(gè)響應(yīng)式的UI來反應(yīng)當(dāng)前耗時(shí)操作的進(jìn)度。 那豈不是用來做進(jìn)度條再合適不過了,可以利用單獨(dú)線程來執(zhí)行耗時(shí)操作,還能反應(yīng)操作的進(jìn)度。
當(dāng)然,如果你要使用它提供的方法,必須要先設(shè)置一下它的某些屬性,不然就沒法使用,比如:要使用ReportProgress()(報(bào)告進(jìn)度)的方法,先要設(shè)置WorkerReportsProgress=true。其他的設(shè)置,可以查官方文檔哦。
private BackgroundWorker bgworker = new BackgroundWorker();
private void button3_Click(object sender, RoutedEventArgs e)
{
InitWork();
bgworker.RunWorkerAsync();
}
/// <summary>
/// 初始化bgwork
/// </summary>
private void InitWork()
{
bgworker.WorkerReportsProgress = true;
bgworker.DoWork += new DoWorkEventHandler(DoWork);
bgworker.ProgressChanged += new ProgressChangedEventHandler(BgworkChange);
}
private void DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
bgworker.ReportProgress(i);
Thread.Sleep(100);
}
}
/// <summary>
///改變進(jìn)度條的值
/// </summary>
private void BgworkChange(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}

源代碼
//mainwindow.xaml
<Window x:Class="progressbartest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ProgressBar Height="23" HorizontalAlignment="Left" Margin="32,124,0,0" Name="progressBar1" VerticalAlignment="Top" Width="432" />
<Button Content="多線程開始" Height="23" HorizontalAlignment="Left" Margin="123,54,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<Button Content="新窗口開始" Height="23" HorizontalAlignment="Left" Margin="219,54,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
<Button Content="BackgroundWorker方式" Height="23" HorizontalAlignment="Left" Margin="310,54,0,0" Name="button3" VerticalAlignment="Top" Width="154" Click="button3_Click" />
<Button Content="開始" Height="23" HorizontalAlignment="Left" Margin="32,54,0,0" Name="button4" VerticalAlignment="Top" Width="75" Click="button4_Click" />
</Grid>
</Window>
//mainwindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.ComponentModel;
namespace progressbartest
{
/// <summary>
/// MainWindow.xaml 的交互邏輯
/// </summary>
public partial class MainWindow : Window
{
private BackgroundWorker bgworker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ProgressBegin();
}
private void ProgressBegin()
{
Thread thread = new Thread(new ThreadStart(() =>
{
for (int i = 0; i <= 100; i++)
{
this.progressBar1.Dispatcher.BeginInvoke((ThreadStart)delegate{ this.progressBar1.Value = i; });
Thread.Sleep(100);
}
}));
thread.Start();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
Window1 window = new Window1();
window.Show();
}
/// <summary>
/// 初始化bgwork
/// </summary>
private void InitWork()
{
bgworker.WorkerReportsProgress = true;
bgworker.DoWork += new DoWorkEventHandler(DoWork);
bgworker.ProgressChanged += new ProgressChangedEventHandler(BgworkChange);
}
private void DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
bgworker.ReportProgress(i);
Thread.Sleep(100);
}
}
/// <summary>
///改變進(jìn)度條的值
/// </summary>
private void BgworkChange(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private void button3_Click(object sender, RoutedEventArgs e)
{
InitWork();
bgworker.RunWorkerAsync();
}
private void button4_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
progressBar1.Value = i;
Thread.Sleep(10);
}
}
}
}
//window1.xaml
<Window x:Class="progressbartest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="217" Width="300">
<Grid>
<ProgressBar Height="24" HorizontalAlignment="Left" Margin="12,72,0,0" Name="progressBar1" VerticalAlignment="Top" Width="254" Foreground="#FF2EAFF1" />
</Grid>
</Window>
//window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Threading;
namespace progressbartest
{
/// <summary>
/// Window1.xaml 的交互邏輯
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
ProgressBegin();
}
private void ProgressBegin()
{
Thread thread = new Thread(new ThreadStart(() =>
{
for (int i = 0; i <= 100; i++)
{
this.progressBar1.Dispatcher.BeginInvoke((ThreadStart)delegate { this.progressBar1.Value = i; });
Thread.Sleep(100);
}
}));
thread.Start();
}
}
}