2013/07/09

WPF ToolKit BusyIndicator

這次介紹的是一個WPF ToolKit中的一個元件『BusyIndicator』,這個元件能夠提供更直覺得介面
當背後服務正在執行時能夠跳出一個Loading的介面,可以讓程式更直覺

首先先去下載Extended WPF Toolkit Binaries,如果是Web可以下載Extended WPF Toolkit Live Explorer

下載下來後,將其解壓縮。開啟VS,在此用VS2010示範

先將該Xceed.Wpf.Toolkit.dll加入到該專案參考



加入完後,這個範例主要是有一個背景的執行續在執行,執行時會有一個Waiting的視窗出現,等到執行完畢後會讓Waiting視窗消失

xaml檔案務必要加入
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
否則會無法使用

一開始就先將BusyIndicator元件新增好,並且將IsBusy改成False
<xctk:BusyIndicator IsBusy="False" BusyContent="Waiting..." Name="busyIndicator" />


<Window x:Class="WpfApplication_Plugin.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid>
        <xctk:BusyIndicator IsBusy="False" BusyContent="Waiting..." Name="busyIndicator" />
        <ProgressBar Height="10" HorizontalAlignment="Left" Margin="168,20,0,0" Name="progressBar1" VerticalAlignment="Top" Width="100" />
        </Grid>
</Window>


程式的流程大概是用一個背景執行續在跑,每秒執行一次,執行完該次工作會將工作量回饋到該背景執行續。透過該回饋值可以去更新progressBar1元件的數值,等到更新完畢後直接將busyIndicator的IsBusy改成false

using System.Windows;
using System.Threading;
using System.ComponentModel;

namespace WpfApplication_Plugin
{
    /// 
    /// MainWindow.xaml 的互動邏輯
    /// 
    public partial class MainWindow : Window
    {
        BackgroundWorker bw = new BackgroundWorker();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            busyIndicator.IsBusy = true;
            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += DoWorkEvent;
            bw.RunWorkerCompleted += RunWorkerCompletedEvent;
            bw.ProgressChanged += ProgressChanged;
            bw.RunWorkerAsync();
        }

        private void DoWorkEvent(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;
            for (int index = 1; index <= 10; index++)
            {
                if (!worker.CancellationPending)
                {
                    Thread.Sleep(1000);
                    worker.ReportProgress(index * 10);
                }
                else
                {
                    e.Cancel = true;
                    break;
                }
            }
        }

        private void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        private void RunWorkerCompletedEvent(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show("已取消了");
            }
            else if (e.Error != null)
            {
                MessageBox.Show("Error");
            }
            else
            {
                busyIndicator.IsBusy = false;
                MessageBox.Show("Done");
            }
        }

    }
}

執行中


執行完畢



參考資料:
http://wpftoolkit.codeplex.com/wikipage?title=BusyIndicator
http://www.dotblogs.com.tw/eternaltung/archive/2010/08/31/silverlightbusyindicator.aspx
http://www.c-sharpcorner.com/UploadFile/mahesh/wpf-busyindicator/