400 lines
15 KiB
C#
400 lines
15 KiB
C#
using Prism.Commands;
|
|
using Prism.Events;
|
|
using Prism.Ioc;
|
|
using Prism.Mvvm;
|
|
using Microsoft.Win32;
|
|
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Configuration;
|
|
using System.IO;
|
|
using System.Windows;
|
|
using System.Windows.Media.Imaging;
|
|
using XplorePlane.Events;
|
|
using XP.Common.Logging.Interfaces;
|
|
using XP.Common.PdfViewer.Interfaces;
|
|
using XP.Hardware.MotionControl.Abstractions;
|
|
|
|
namespace XplorePlane.ViewModels
|
|
{
|
|
public class MainViewModel : BindableBase
|
|
{
|
|
private readonly ILoggerService _logger;
|
|
private readonly IContainerProvider _containerProvider;
|
|
private readonly IEventAggregator _eventAggregator;
|
|
private string _licenseInfo = "当前时间";
|
|
|
|
public string LicenseInfo
|
|
{
|
|
get => _licenseInfo;
|
|
set => SetProperty(ref _licenseInfo, value);
|
|
}
|
|
|
|
public ObservableCollection<object> NavigationTree { get; set; }
|
|
|
|
// 导航命令
|
|
public DelegateCommand NavigateHomeCommand { get; set; }
|
|
public DelegateCommand NavigateInspectCommand { get; set; }
|
|
public DelegateCommand OpenFileCommand { get; set; }
|
|
public DelegateCommand ExportCommand { get; set; }
|
|
public DelegateCommand ClearCommand { get; set; }
|
|
public DelegateCommand EditPropertiesCommand { get; set; }
|
|
|
|
// 窗口打开命令
|
|
public DelegateCommand OpenImageProcessingCommand { get; }
|
|
public DelegateCommand LoadImageCommand { get; }
|
|
public DelegateCommand OpenPipelineEditorCommand { get; }
|
|
public DelegateCommand OpenCncEditorCommand { get; }
|
|
public DelegateCommand OpenMatrixEditorCommand { get; }
|
|
public DelegateCommand OpenToolboxCommand { get; }
|
|
public DelegateCommand OpenLibraryVersionsCommand { get; }
|
|
public DelegateCommand OpenUserManualCommand { get; }
|
|
public DelegateCommand OpenCameraSettingsCommand { get; }
|
|
|
|
// 硬件命令
|
|
public DelegateCommand AxisResetCommand { get; }
|
|
public DelegateCommand OpenDetectorConfigCommand { get; }
|
|
public DelegateCommand OpenMotionDebugCommand { get; }
|
|
public DelegateCommand OpenPlcAddrConfigCommand { get; }
|
|
public DelegateCommand OpenRaySourceConfigCommand { get; }
|
|
public DelegateCommand WarmUpCommand { get; }
|
|
|
|
// 设置命令
|
|
public DelegateCommand OpenLanguageSwitcherCommand { get; }
|
|
public DelegateCommand OpenRealTimeLogViewerCommand { get; }
|
|
|
|
// 窗口引用(单例窗口防止重复打开)
|
|
private Window _motionDebugWindow;
|
|
private Window _detectorConfigWindow;
|
|
private Window _plcAddrConfigWindow;
|
|
private Window _realTimeLogViewerWindow;
|
|
private Window _toolboxWindow;
|
|
private Window _raySourceConfigWindow;
|
|
|
|
public MainViewModel(ILoggerService logger, IContainerProvider containerProvider, IEventAggregator eventAggregator)
|
|
{
|
|
_logger = logger?.ForModule<MainViewModel>() ?? throw new ArgumentNullException(nameof(logger));
|
|
_containerProvider = containerProvider ?? throw new ArgumentNullException(nameof(containerProvider));
|
|
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
|
|
|
NavigationTree = new ObservableCollection<object>();
|
|
|
|
// 导航命令
|
|
NavigateHomeCommand = new DelegateCommand(OnNavigateHome);
|
|
NavigateInspectCommand = new DelegateCommand(OnNavigateInspect);
|
|
OpenFileCommand = new DelegateCommand(OnOpenFile);
|
|
ExportCommand = new DelegateCommand(OnExport);
|
|
ClearCommand = new DelegateCommand(OnClear);
|
|
EditPropertiesCommand = new DelegateCommand(OnEditProperties);
|
|
|
|
// 窗口打开命令
|
|
OpenImageProcessingCommand = new DelegateCommand(() => ShowWindow(new Views.ImageProcessingWindow(), "图像处理"));
|
|
LoadImageCommand = new DelegateCommand(ExecuteLoadImage);
|
|
OpenPipelineEditorCommand = new DelegateCommand(() => ShowWindow(new Views.PipelineEditorWindow(), "流水线编辑器"));
|
|
OpenCncEditorCommand = new DelegateCommand(() => ShowWindow(new Views.Cnc.CncEditorWindow(), "CNC 编辑器"));
|
|
OpenMatrixEditorCommand = new DelegateCommand(() => ShowWindow(new Views.Cnc.MatrixEditorWindow(), "矩阵编排"));
|
|
OpenToolboxCommand = new DelegateCommand(ExecuteOpenToolbox);
|
|
OpenLibraryVersionsCommand = new DelegateCommand(() => ShowWindow(new Views.LibraryVersionsWindow(), "关于"));
|
|
OpenUserManualCommand = new DelegateCommand(ExecuteOpenUserManual);
|
|
OpenCameraSettingsCommand = new DelegateCommand(ExecuteOpenCameraSettings);
|
|
|
|
// 硬件命令
|
|
AxisResetCommand = new DelegateCommand(ExecuteAxisReset);
|
|
OpenDetectorConfigCommand = new DelegateCommand(ExecuteOpenDetectorConfig);
|
|
OpenMotionDebugCommand = new DelegateCommand(ExecuteOpenMotionDebug);
|
|
OpenPlcAddrConfigCommand = new DelegateCommand(ExecuteOpenPlcAddrConfig);
|
|
OpenRaySourceConfigCommand = new DelegateCommand(ExecuteOpenRaySourceConfig);
|
|
WarmUpCommand = new DelegateCommand(ExecuteWarmUp);
|
|
|
|
// 设置命令
|
|
OpenLanguageSwitcherCommand = new DelegateCommand(ExecuteOpenLanguageSwitcher);
|
|
OpenRealTimeLogViewerCommand = new DelegateCommand(ExecuteOpenRealTimeLogViewer);
|
|
|
|
_logger.Info("MainViewModel 已初始化");
|
|
}
|
|
|
|
#region 通用窗口辅助方法
|
|
|
|
/// <summary>
|
|
/// 显示一个新窗口(非模态)
|
|
/// </summary>
|
|
private void ShowWindow(Window window, string name)
|
|
{
|
|
window.Owner = Application.Current.MainWindow;
|
|
window.Show();
|
|
_logger.Info("{Name} 窗口已打开", name);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 显示或激活单例窗口(非模态,防止重复打开)
|
|
/// </summary>
|
|
private void ShowOrActivate(Window currentWindow, Action<Window> setWindow, Func<Window> factory, string name)
|
|
{
|
|
if (currentWindow != null && currentWindow.IsLoaded)
|
|
{
|
|
currentWindow.Activate();
|
|
return;
|
|
}
|
|
|
|
var window = factory();
|
|
window.Owner = Application.Current.MainWindow;
|
|
window.ShowInTaskbar = true;
|
|
window.Closed += (s, e) => setWindow(null);
|
|
window.Show();
|
|
setWindow(window);
|
|
_logger.Info("{Name} 窗口已打开", name);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 窗口打开命令实现
|
|
|
|
private void ExecuteOpenToolbox()
|
|
{
|
|
ShowOrActivate(_toolboxWindow, w => _toolboxWindow = w, () => new Views.OperatorToolboxWindow(), "算子工具箱");
|
|
}
|
|
|
|
private void ExecuteOpenUserManual()
|
|
{
|
|
try
|
|
{
|
|
var manualPath = ConfigurationManager.AppSettings["UserManual"];
|
|
if (string.IsNullOrEmpty(manualPath))
|
|
{
|
|
_logger.Warn("未配置用户手册路径");
|
|
MessageBox.Show("未配置用户手册路径,请检查 App.config 中的 UserManual 配置项。",
|
|
"提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
return;
|
|
}
|
|
|
|
if (!File.Exists(manualPath))
|
|
{
|
|
_logger.Warn("用户手册文件不存在:{Path}", manualPath);
|
|
MessageBox.Show($"用户手册文件不存在:\n{manualPath}",
|
|
"提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
return;
|
|
}
|
|
|
|
var pdfViewerService = _containerProvider.Resolve<IPdfViewerService>();
|
|
var stream = File.OpenRead(manualPath);
|
|
var fileName = Path.GetFileName(manualPath);
|
|
pdfViewerService.OpenViewer(stream, fileName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "打开用户手册失败");
|
|
MessageBox.Show($"打开用户手册失败:{ex.Message}",
|
|
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
private void ExecuteOpenCameraSettings()
|
|
{
|
|
try
|
|
{
|
|
var vm = _containerProvider.Resolve<NavigationPropertyPanelViewModel>();
|
|
if (!vm.IsCameraConnected)
|
|
{
|
|
MessageBox.Show("请先连接相机", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
return;
|
|
}
|
|
|
|
var window = new Views.CameraSettingsWindow(vm) { Owner = Application.Current.MainWindow };
|
|
window.Show();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "打开相机设置失败");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 硬件命令实现
|
|
|
|
private void ExecuteAxisReset()
|
|
{
|
|
var result = MessageBox.Show("确认执行轴复位操作?", "轴复位",
|
|
MessageBoxButton.OKCancel, MessageBoxImage.Question);
|
|
if (result != MessageBoxResult.OK) return;
|
|
|
|
try
|
|
{
|
|
var motionSystem = _containerProvider.Resolve<IMotionSystem>();
|
|
var resetResult = motionSystem.AxisReset.Reset();
|
|
if (!resetResult.Success)
|
|
{
|
|
MessageBox.Show($"轴复位失败:{resetResult.ErrorMessage}", "错误",
|
|
MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "轴复位异常");
|
|
MessageBox.Show($"轴复位异常:{ex.Message}", "错误",
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
private void ExecuteOpenDetectorConfig()
|
|
{
|
|
try
|
|
{
|
|
ShowOrActivate(_detectorConfigWindow, w => _detectorConfigWindow = w,
|
|
() => new XP.Hardware.Detector.Views.DetectorConfigWindow(), "探测器配置");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "打开探测器配置窗口失败");
|
|
MessageBox.Show($"打开探测器配置窗口失败:\n{ex.InnerException?.Message ?? ex.Message}",
|
|
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
private void ExecuteOpenMotionDebug()
|
|
{
|
|
ShowOrActivate(_motionDebugWindow, w => _motionDebugWindow = w,
|
|
() => new XP.Hardware.MotionControl.Views.MotionDebugWindow(), "运动调试");
|
|
}
|
|
|
|
private void ExecuteOpenPlcAddrConfig()
|
|
{
|
|
ShowOrActivate(_plcAddrConfigWindow, w => _plcAddrConfigWindow = w,
|
|
() => _containerProvider.Resolve<XP.Hardware.PLC.Views.PlcAddrConfigEditorWindow>(), "PLC 地址配置");
|
|
}
|
|
|
|
private void ExecuteOpenRaySourceConfig()
|
|
{
|
|
ShowOrActivate(_raySourceConfigWindow, w => _raySourceConfigWindow = w,
|
|
() => new XP.Hardware.RaySource.Views.RaySourceConfigWindow(), "射线源配置");
|
|
}
|
|
|
|
private void ExecuteLoadImage()
|
|
{
|
|
var dialog = new OpenFileDialog
|
|
{
|
|
Title = "加载图像",
|
|
Filter = "图像文件|*.bmp;*.png;*.jpg;*.jpeg;*.tif;*.tiff|所有文件|*.*"
|
|
};
|
|
|
|
if (dialog.ShowDialog() != true)
|
|
return;
|
|
|
|
try
|
|
{
|
|
var bitmap = new BitmapImage();
|
|
bitmap.BeginInit();
|
|
bitmap.UriSource = new Uri(dialog.FileName, UriKind.Absolute);
|
|
bitmap.CacheOption = BitmapCacheOption.OnLoad;
|
|
bitmap.EndInit();
|
|
bitmap.Freeze();
|
|
|
|
_eventAggregator.GetEvent<ManualImageLoadedEvent>()
|
|
.Publish(new ManualImageLoadedPayload(bitmap, dialog.FileName));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "加载图像失败:{Path}", dialog.FileName);
|
|
MessageBox.Show($"加载图像失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
private void ExecuteWarmUp()
|
|
{
|
|
var messageBoxResult = MessageBox.Show("确认执行射线源暖机操作?", "暖机",
|
|
MessageBoxButton.OKCancel, MessageBoxImage.Question);
|
|
if (messageBoxResult != MessageBoxResult.OK) return;
|
|
|
|
try
|
|
{
|
|
var raySourceService = _containerProvider.Resolve<XP.Hardware.RaySource.Services.IRaySourceService>();
|
|
var result = raySourceService.WarmUp();
|
|
if (!result.Success)
|
|
{
|
|
MessageBox.Show($"暖机失败:{result.ErrorMessage}", "错误",
|
|
MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
}
|
|
else
|
|
{
|
|
_logger.Info("暖机命令已发送");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "暖机异常");
|
|
MessageBox.Show($"暖机异常:{ex.Message}", "错误",
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 设置命令实现
|
|
|
|
private void ExecuteOpenLanguageSwitcher()
|
|
{
|
|
try
|
|
{
|
|
var viewModel = _containerProvider.Resolve<XP.Common.Localization.ViewModels.LanguageSwitcherViewModel>();
|
|
var window = new XP.Common.Localization.Views.LanguageSwitcherWindow(viewModel)
|
|
{
|
|
Owner = Application.Current.MainWindow,
|
|
ShowInTaskbar = true
|
|
};
|
|
window.ShowDialog();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error(ex, "打开语言设置失败");
|
|
}
|
|
}
|
|
|
|
private void ExecuteOpenRealTimeLogViewer()
|
|
{
|
|
ShowOrActivate(_realTimeLogViewerWindow, w => _realTimeLogViewerWindow = w,
|
|
() => new XP.Common.GeneralForm.Views.RealTimeLogViewer(), "实时日志");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 导航命令实现
|
|
|
|
private void OnNavigateHome()
|
|
{
|
|
_logger.Info("导航到主页");
|
|
LicenseInfo = "主页";
|
|
}
|
|
|
|
private void OnNavigateInspect()
|
|
{
|
|
_logger.Info("导航到检测页面");
|
|
LicenseInfo = "检测页面";
|
|
}
|
|
|
|
private void OnOpenFile()
|
|
{
|
|
_logger.Info("打开文件");
|
|
LicenseInfo = "打开文件";
|
|
}
|
|
|
|
private void OnExport()
|
|
{
|
|
_logger.Info("导出数据");
|
|
LicenseInfo = "导出数据";
|
|
}
|
|
|
|
private void OnClear()
|
|
{
|
|
_logger.Info("清除数据");
|
|
LicenseInfo = "清除数据";
|
|
}
|
|
|
|
private void OnEditProperties()
|
|
{
|
|
_logger.Info("编辑属性");
|
|
LicenseInfo = "编辑属性";
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|