【25】WPF ProgressBar進(jìn)度條

進(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)一下,使用多線程。

image.png
多線程開始

我們重新開啟一個(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();
        }

    }
}

image.png
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;
}
image.png
源代碼
//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();
        }

    }
}
參考資料

BackgroundWorker使用總結(jié)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,781評(píng)論 25 709
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,621評(píng)論 1 32
  • 人脈決定財(cái)脈,左右逢源好賺錢。累積你的“人脈存折”。良好的人際關(guān)系帶來意外的財(cái)富。朋友多了好辦事,利用朋友做生意。...
    西瓜狐貍閱讀 276評(píng)論 0 0
  • 不知那些離去的光陰 都去做了什么 歲月已斑駁了我的眼睛 很久不見總是變了許多 不變是鄉(xiāng)間老屋 還在訴說我的童年 門...
    Harvest收獲閱讀 677評(píng)論 88 107
  • 爺爺?shù)纳眢w很健康,他還能像以前做飯,收拾東西。唯一令人遺憾的是他的耳朵特別聾。你說三他扯四,常常令人哭笑不得...
    吳佳妮33閱讀 498評(píng)論 0 1

友情鏈接更多精彩內(nèi)容