Files
OrpaonVision/OrpaonVision.SiteApp/OptimizedMainWindow.xaml.cs
2026-04-06 22:04:05 +08:00

348 lines
9.4 KiB
C#

using Microsoft.Extensions.Logging;
using OrpaonVision.SiteApp.Runtime.Services;
using OrpaonVision.SiteApp.ViewModels;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace OrpaonVision.SiteApp;
/// <summary>
/// 优化的主窗口。
/// </summary>
public partial class OptimizedMainWindow : Window
{
private readonly OptimizedMainWindowViewModel _viewModel;
private readonly ILogger<OptimizedMainWindow> _logger;
private System.Windows.Threading.DispatcherTimer? _autoRunTimer;
/// <summary>
/// 构造函数。
/// </summary>
public OptimizedMainWindow(OptimizedMainWindowViewModel viewModel, ILogger<OptimizedMainWindow> logger)
{
_viewModel = viewModel;
_logger = logger;
InitializeComponent();
DataContext = _viewModel;
Title = "OrpaonVision 运行端 - 实时图像检测";
// 初始化自动运行定时器
InitializeAutoRunTimer();
_logger.LogInformation("优化主窗口已初始化");
}
/// <summary>
/// 执行一轮检测点击事件。
/// </summary>
private void OnRunOneCycleClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.RunOneCycle();
_logger.LogInformation("手动执行一轮检测完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "执行一轮检测失败");
MessageBox.Show($"执行检测失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 切换下一层点击事件。
/// </summary>
private void OnMoveNextLayerClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.MoveToNextLayer();
_logger.LogInformation("切换到下一层完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "切换下一层失败");
MessageBox.Show($"切换下一层失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 重置运行状态点击事件。
/// </summary>
private void OnResetRuntimeClicked(object sender, RoutedEventArgs e)
{
try
{
// 停止自动运行
if (_viewModel.IsAutoRunning)
{
_viewModel.ToggleAutoRun();
}
_viewModel.ResetRuntime();
_logger.LogInformation("重置运行状态完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "重置运行状态失败");
MessageBox.Show($"重置状态失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 切换自动运行点击事件。
/// </summary>
private void OnToggleAutoRunClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ToggleAutoRun();
UpdateAutoRunTimer();
_logger.LogInformation("切换自动运行状态: {IsRunning}", _viewModel.IsAutoRunning);
}
catch (Exception ex)
{
_logger.LogError(ex, "切换自动运行失败");
MessageBox.Show($"切换自动运行失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 保存图像点击事件。
/// </summary>
private void OnSaveImageClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.SaveCurrentImage();
}
catch (Exception ex)
{
_logger.LogError(ex, "保存图像失败");
MessageBox.Show($"保存图像失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
/// <summary>
/// 无滤镜点击事件。
/// </summary>
private void OnFilterNoneClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ApplyImageFilter(ImageFilter.None);
}
catch (Exception ex)
{
_logger.LogError(ex, "应用无滤镜失败");
}
}
/// <summary>
/// 灰度滤镜点击事件。
/// </summary>
private void OnFilterGrayscaleClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ApplyImageFilter(ImageFilter.Grayscale);
}
catch (Exception ex)
{
_logger.LogError(ex, "应用灰度滤镜失败");
}
}
/// <summary>
/// 二值化滤镜点击事件。
/// </summary>
private void OnFilterBinaryClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ApplyImageFilter(ImageFilter.Binary);
}
catch (Exception ex)
{
_logger.LogError(ex, "应用二值化滤镜失败");
}
}
/// <summary>
/// 边缘检测滤镜点击事件。
/// </summary>
private void OnFilterEdgeClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ApplyImageFilter(ImageFilter.EdgeDetection);
}
catch (Exception ex)
{
_logger.LogError(ex, "应用边缘检测滤镜失败");
}
}
/// <summary>
/// 模糊滤镜点击事件。
/// </summary>
private void OnFilterBlurClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ApplyImageFilter(ImageFilter.Blur);
}
catch (Exception ex)
{
_logger.LogError(ex, "应用模糊滤镜失败");
}
}
/// <summary>
/// 锐化滤镜点击事件。
/// </summary>
private void OnFilterSharpenClicked(object sender, RoutedEventArgs e)
{
try
{
_viewModel.ApplyImageFilter(ImageFilter.Sharpen);
}
catch (Exception ex)
{
_logger.LogError(ex, "应用锐化滤镜失败");
}
}
/// <summary>
/// 初始化自动运行定时器。
/// </summary>
private void InitializeAutoRunTimer()
{
_autoRunTimer = new System.Windows.Threading.DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(1000 / _viewModel.FrameRate)
};
_autoRunTimer.Tick += OnAutoRunTimerTick;
// 监听帧率变化
_viewModel.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == nameof(_viewModel.FrameRate))
{
UpdateAutoRunTimer();
}
};
}
/// <summary>
/// 更新自动运行定时器。
/// </summary>
private void UpdateAutoRunTimer()
{
if (_autoRunTimer == null)
return;
if (_viewModel.IsAutoRunning)
{
_autoRunTimer.Interval = TimeSpan.FromMilliseconds(1000 / _viewModel.FrameRate);
_autoRunTimer.Start();
}
else
{
_autoRunTimer.Stop();
}
}
/// <summary>
/// 自动运行定时器触发事件。
/// </summary>
private void OnAutoRunTimerTick(object? sender, EventArgs e)
{
try
{
_viewModel.RunOneCycle();
}
catch (Exception ex)
{
_logger.LogError(ex, "自动运行检测失败");
// 自动运行出错时停止自动运行
_viewModel.ToggleAutoRun();
UpdateAutoRunTimer();
Dispatcher.Invoke(() =>
{
MessageBox.Show($"自动运行出错,已停止: {ex.Message}", "自动运行错误", MessageBoxButton.OK, MessageBoxImage.Warning);
});
}
}
/// <summary>
/// 窗口关闭事件。
/// </summary>
protected override void OnClosed(EventArgs e)
{
try
{
// 停止自动运行
if (_autoRunTimer != null)
{
_autoRunTimer.Stop();
_autoRunTimer.Tick -= OnAutoRunTimerTick;
}
_logger.LogInformation("优化主窗口已关闭");
}
catch (Exception ex)
{
_logger.LogError(ex, "关闭窗口时出错");
}
base.OnClosed(e);
}
}
/// <summary>
/// 布尔值到自动运行文本转换器。
/// </summary>
public class BoolToAutoRunTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool isRunning)
{
return isRunning ? "停止自动运行" : "启动自动运行";
}
return "启动自动运行";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 布尔值到自动运行颜色转换器。
/// </summary>
public class BoolToAutoRunColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool isRunning)
{
return isRunning ? Brushes.OrangeRed : Brushes.DarkGreen;
}
return Brushes.DarkGreen;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}