WPF弹出进度条窗口

发现WPF没有相关进度条窗口组件,于是基于MaterialDesignThemes的ProgressBar样式写了一个 ,其中用到了PropertyChanged.Fody包。

 

  • 关键点
  1. 去除窗口关闭按钮 DialogHelper.RemoveCloseBtn(this);
  2. 窗口置顶 void Window_Deactivated(object sender, EventArgs e)
  3. 刷新数值 void OnNumChanged()
  4. 自动关闭 override void OnClosing(System.ComponentModel.CancelEventArgs e)

  • 新建进度条窗口 ProgressBarWinControl.xaml

    
        
        
    

  • ProgressBarWinControl.xaml.cs 代码
using NmsCoreApp.Util;
using PropertyChanged;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
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.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace NmsCoreApp.Controls
{
    /// 
    /// ProgressBarWinControl.xaml 的交互逻辑
    /// 
    [AddINotifyPropertyChangedInterface]
    public partial class ProgressBarWinControl : Window
    {
       
        public int Num { set; get; } = 1;
        public string MContent { set; get; } = "";
        
        public ProgressBarWinControl()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        private void OnNumChanged()
        {
            if(Num == 100)
            {
                this.Close();
            }
        }

        public void InvokeUpdate(int Num, string MContent)
        {
            this.Dispatcher.Invoke(() =>
            {
                this.Num = Num;
                this.MContent = MContent;
            });
        }
        public void InvokeAsync(Action a)
        {
            this.Dispatcher.InvokeAsync(a);
        }
        public void Invoke(Action a)
        {
            this.Dispatcher.Invoke(a);
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if(Num < 100)
            {
                e.Cancel = true;
            }
        }
        private void Window_Deactivated(object sender, EventArgs e)
        {
            Window window = (Window)sender;
            window.Topmost = true;
            Console.WriteLine("工具条窗口置顶");
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DialogHelper.RemoveCloseBtn(this);


        }
    }
}
  • DialogHelper类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;

namespace NmsCoreApp.Util
{
    public class DialogHelper
    {
        private const int GWL_STYLE = -16;
        private const int WS_SYSMENU = 0x80000;
        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        //从Handle中获取Window对象
        static Window GetWindowFromHwnd(IntPtr hwnd)
        {
            return (Window)HwndSource.FromHwnd(hwnd).RootVisual;
        }

        //GetForegroundWindow API
        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        //调用GetForegroundWindow然后调用GetWindowFromHwnd
        static Window GetTopWindow()
        {
            var hwnd = GetForegroundWindow();
            if (hwnd == null)
                return null;

            return GetWindowFromHwnd(hwnd);
        }



        //显示对话框并自动设置Owner,可以理解为子窗体添加父窗体
        public static void ShowDialog(Window win)
        {
            win.Owner = GetTopWindow();
            win.ShowInTaskbar = false;       //false表示不显示新的窗口,默认当前打开窗口为一个子窗口(不会显示两个窗口)
            win.ShowDialog();
        }
        //显示对话框并自动设置Owner,可以理解为子窗体添加父窗体
        public static void Show(Window win)
        {
            win.Owner = GetTopWindow();
            win.ShowInTaskbar = false;       //false表示不显示新的窗口,默认当前打开窗口为一个子窗口(不会显示两个窗口)
            win.Show();
        }

        public static void RemoveCloseBtn(Window win)
        {
            var hwnd = new WindowInteropHelper(win).Handle;
            SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);

        }
    }
}
  • 测试调用代码
ProgressBarWinControl progressBarWinControl = new ProgressBarWinControl();

               DialogHelper.Show(progressBarWinControl);
               await Task.Run(() =>
               {
                   progressBarWinControl.InvokeAsync(() => {
                       progressBarWinControl.Title = "关闭测试";
                   });
                   for (int i = 1; i <= 100; i++)
                   {
                       Thread.Sleep(150);
                       progressBarWinControl.Dispatcher.Invoke(() =>
                       {
                           
                           progressBarWinControl.Num = i;
                           progressBarWinControl.MContent = "执行第" + i + "个";

                       });
                   }
           });

你可能感兴趣的:(WPF,c#,wpf)