97 lines
3.0 KiB
C#
97 lines
3.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Linq;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Threading;
|
||
|
||
namespace ShrlAlgo.Addin.Test
|
||
{
|
||
// 用于给外界调用的报告器
|
||
public class ProgressReporter
|
||
{
|
||
private readonly ProgressViewModel _viewModel;
|
||
private DateTime _lastUpdate = DateTime.MinValue;
|
||
|
||
public ProgressReporter(ProgressViewModel viewModel)
|
||
{
|
||
_viewModel = viewModel;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新进度 (自带节流控制,防止频繁更新导致UI卡顿)
|
||
/// </summary>
|
||
public void Report(int current, int total, string message = null)
|
||
{
|
||
// 限制 UI 刷新频率(每 50 毫秒最多刷新一次)
|
||
if ((DateTime.Now - _lastUpdate).TotalMilliseconds < 50 && current != total)
|
||
return;
|
||
|
||
_lastUpdate = DateTime.Now;
|
||
_viewModel.Update(current, total, message);
|
||
}
|
||
|
||
public void ReportMessage(string message) => _viewModel.UpdateMessage(message);
|
||
}
|
||
|
||
// WPF 的 ViewModel
|
||
public class ProgressViewModel : INotifyPropertyChanged
|
||
{
|
||
private readonly CancellationTokenSource _cts;
|
||
public Dispatcher UIDispatcher { get; set; }
|
||
public Action CloseAction { get; set; }
|
||
|
||
public ProgressViewModel(string title, CancellationTokenSource cts)
|
||
{
|
||
Title = title;
|
||
_cts = cts;
|
||
}
|
||
|
||
private string _title;
|
||
public string Title { get => _title; set => SetProperty(ref _title, value); }
|
||
|
||
private string _message = "正在准备...";
|
||
public string Message { get => _message; set => SetProperty(ref _message, value); }
|
||
|
||
private double _progressValue;
|
||
public double ProgressValue { get => _progressValue; set => SetProperty(ref _progressValue, value); }
|
||
|
||
private double _maximum = 100;
|
||
public double Maximum { get => _maximum; set => SetProperty(ref _maximum, value); }
|
||
|
||
public void Cancel()
|
||
{
|
||
if (!_cts.IsCancellationRequested)
|
||
{
|
||
Message = "正在取消任务,请稍候...";
|
||
_cts.Cancel();
|
||
}
|
||
}
|
||
|
||
// 跨线程更新 UI
|
||
public void Update(int current, int total, string message)
|
||
{
|
||
UIDispatcher?.InvokeAsync(() =>
|
||
{
|
||
ProgressValue = current;
|
||
Maximum = total;
|
||
if (!string.IsNullOrEmpty(message)) Message = message;
|
||
});
|
||
}
|
||
|
||
public void UpdateMessage(string message)
|
||
{
|
||
UIDispatcher?.InvokeAsync(() => Message = message);
|
||
}
|
||
|
||
public event PropertyChangedEventHandler PropertyChanged;
|
||
protected void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||
{
|
||
field = value;
|
||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||
}
|
||
}
|
||
}
|