WPF中實現彈出進度條視窗

Ritchie.Lee發表於2024-11-22

實現功能:

模擬一個任務開始執行,在視窗彈出一個進度條,展示執行進度,執行完成彈出提示框。例如做資料查詢時,如果查詢需要一段時間,操作人員可以很好的知道是否查詢完成。

1. 設計進度條彈出視窗

進度條視窗樣式設計 XAML

<Window x:Class="WpfApp.ProgressBarWindow"
        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:WpfApp"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        WindowStyle="None" 
        ResizeMode="NoResize"
        AllowsTransparency="True"
        Topmost="True"
        Title="ProgressBarWindow" Height="100" Width="800">
    <Grid>
        <ProgressBar Margin="5" x:Name="progressBar1" 
                     HorizontalAlignment="Stretch" 
                     Height="90" 
                     VerticalAlignment="Center" 
                     DataContext="{Binding}" 
                     Value="{Binding Progress}"
                     Foreground="LightGreen"
                     >
           
        </ProgressBar>
    </Grid>
</Window>

進度條視窗後臺程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace WpfApp
{
    /// <summary>
    /// ProgressBarWindow.xaml 的互動邏輯
    /// </summary>
    public partial class ProgressBarWindow : Window
    {
        public ProgressBarWindow()
        {
            InitializeComponent();
            DataContext = new ProgressViewModel(this);
        }
    }
}

  

2.建立進度條檢視模型ProgressViewModel

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace WpfApp
{
    public class ProgressViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;


        private Window myWindow;
        public ProgressViewModel(Window wnd)
        {
            myWindow = wnd;
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private int _progress;
        public int Progress
        {
            get { return _progress; }

            set
            {
                _progress = value;

                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Progress)));
                if (_progress == 100)
                {
                    // 關閉進度視窗
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        myWindow.Close();

                    });
                }
            }
        }
    }
}

 

3. 建立測試主視窗

主視窗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:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <Grid>
        <Button x:Name="btnTest" FontSize="18" Click="btnTest_Click" Margin="10 30  10 30">開始任務...</Button>
    </Grid>
</Window>

  

主視窗後臺程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace WpfApp
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }


        private static ProgressBarWindow pgbWindow;

        private async void btnTest_Click(object sender, RoutedEventArgs e)
        {

            // 建立進度視窗
            pgbWindow = new ProgressBarWindow();
            pgbWindow.Show();

            // 模擬耗時任務
            await Task.Run(() =>
            {
                for (int i = 0; i <= 100; i++)
                {
                    pgbWindow.Dispatcher.Invoke(() =>
                    {
                        pgbWindow.progressBar1.Value= i;
                        Console.WriteLine(i);
                       
                    });
                    System.Threading.Thread.Sleep(20);
                }
            });


            MessageBox.Show("任務完成!");
        }
    }
}

  

4. 測試驗證如下

相關文章