Files
ShrlAlgoToolkit/ShrlAlgo.Addin.Test/ProgressReporter.cs

97 lines
3.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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));
}
}
}