修复CNC模式下,+号订阅事件;修复CNC和普通模式的切换问题
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -324,6 +324,9 @@ namespace XplorePlane.ViewModels.Cnc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>供外部直接 await 的保存方法</summary>
|
||||||
|
public Task SaveAsync() => ExecuteSaveProgramAsync();
|
||||||
|
|
||||||
private async Task ExecuteSaveProgramAsync()
|
private async Task ExecuteSaveProgramAsync()
|
||||||
{
|
{
|
||||||
if (_currentProgram == null)
|
if (_currentProgram == null)
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ namespace XplorePlane.ViewModels.Cnc
|
|||||||
|
|
||||||
_editorViewModel.PropertyChanged += OnEditorPropertyChanged;
|
_editorViewModel.PropertyChanged += OnEditorPropertyChanged;
|
||||||
RefreshFromSelection();
|
RefreshFromSelection();
|
||||||
|
|
||||||
|
_eventAggregator?.GetEvent<AddOperatorRequestedEvent>()
|
||||||
|
.Subscribe(key => { if (CanAddOperator(key)) AddOperator(key); });
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<PipelineNodeViewModel> PipelineNodes { get; }
|
public ObservableCollection<PipelineNodeViewModel> PipelineNodes { get; }
|
||||||
@@ -174,6 +177,9 @@ namespace XplorePlane.ViewModels.Cnc
|
|||||||
RaiseCommandCanExecuteChanged();
|
RaiseCommandCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CanAddOperator(string operatorKey) =>
|
||||||
|
HasActiveModule && !string.IsNullOrWhiteSpace(operatorKey);
|
||||||
|
|
||||||
private void AddOperator(string operatorKey)
|
private void AddOperator(string operatorKey)
|
||||||
{
|
{
|
||||||
if (!HasActiveModule || string.IsNullOrWhiteSpace(operatorKey))
|
if (!HasActiveModule || string.IsNullOrWhiteSpace(operatorKey))
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace XplorePlane.ViewModels
|
|||||||
private string _pipelineFileDisplayName = DefaultPipelineFileDisplayName;
|
private string _pipelineFileDisplayName = DefaultPipelineFileDisplayName;
|
||||||
private string _currentFilePath;
|
private string _currentFilePath;
|
||||||
private PipelineNodeViewModel _executionEndNode;
|
private PipelineNodeViewModel _executionEndNode;
|
||||||
|
private bool _isModified;
|
||||||
|
|
||||||
private CancellationTokenSource _executionCts;
|
private CancellationTokenSource _executionCts;
|
||||||
private CancellationTokenSource _debounceCts;
|
private CancellationTokenSource _debounceCts;
|
||||||
@@ -172,6 +173,13 @@ namespace XplorePlane.ViewModels
|
|||||||
private set => SetProperty(ref _pipelineFileDisplayName, value);
|
private set => SetProperty(ref _pipelineFileDisplayName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>流水线是否有未保存的修改</summary>
|
||||||
|
public bool IsModified
|
||||||
|
{
|
||||||
|
get => _isModified;
|
||||||
|
private set => SetProperty(ref _isModified, value);
|
||||||
|
}
|
||||||
|
|
||||||
public PipelineNodeViewModel ExecutionEndNode
|
public PipelineNodeViewModel ExecutionEndNode
|
||||||
{
|
{
|
||||||
get => _executionEndNode;
|
get => _executionEndNode;
|
||||||
@@ -266,6 +274,7 @@ namespace XplorePlane.ViewModels
|
|||||||
_logger.Info("节点已添加到 PipelineNodes:{Key} ({DisplayName}),当前节点数={Count}",
|
_logger.Info("节点已添加到 PipelineNodes:{Key} ({DisplayName}),当前节点数={Count}",
|
||||||
operatorKey, displayName, PipelineNodes.Count);
|
operatorKey, displayName, PipelineNodes.Count);
|
||||||
SetInfoStatus($"已添加算子:{displayName}");
|
SetInfoStatus($"已添加算子:{displayName}");
|
||||||
|
IsModified = true;
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +292,7 @@ namespace XplorePlane.ViewModels
|
|||||||
SelectNeighborAfterRemoval(removedIndex);
|
SelectNeighborAfterRemoval(removedIndex);
|
||||||
|
|
||||||
SetInfoStatus($"已移除算子:{node.DisplayName}");
|
SetInfoStatus($"已移除算子:{node.DisplayName}");
|
||||||
|
IsModified = true;
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,6 +304,7 @@ namespace XplorePlane.ViewModels
|
|||||||
PipelineNodes.Move(index, index - 1);
|
PipelineNodes.Move(index, index - 1);
|
||||||
RenumberNodes();
|
RenumberNodes();
|
||||||
UpdateExecutionRangeState();
|
UpdateExecutionRangeState();
|
||||||
|
IsModified = true;
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +316,7 @@ namespace XplorePlane.ViewModels
|
|||||||
PipelineNodes.Move(index, index + 1);
|
PipelineNodes.Move(index, index + 1);
|
||||||
RenumberNodes();
|
RenumberNodes();
|
||||||
UpdateExecutionRangeState();
|
UpdateExecutionRangeState();
|
||||||
|
IsModified = true;
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,6 +337,7 @@ namespace XplorePlane.ViewModels
|
|||||||
UpdateExecutionRangeState();
|
UpdateExecutionRangeState();
|
||||||
SelectedNode = node;
|
SelectedNode = node;
|
||||||
SetInfoStatus($"已调整算子顺序:{node.DisplayName}");
|
SetInfoStatus($"已调整算子顺序:{node.DisplayName}");
|
||||||
|
IsModified = true;
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +350,7 @@ namespace XplorePlane.ViewModels
|
|||||||
SetInfoStatus(node.IsEnabled
|
SetInfoStatus(node.IsEnabled
|
||||||
? $"已启用算子:{node.DisplayName}"
|
? $"已启用算子:{node.DisplayName}"
|
||||||
: $"已停用算子:{node.DisplayName}");
|
: $"已停用算子:{node.DisplayName}");
|
||||||
|
IsModified = true;
|
||||||
TriggerDebouncedExecution();
|
TriggerDebouncedExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +420,7 @@ namespace XplorePlane.ViewModels
|
|||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(ProcessorParameterVM.Value))
|
if (e.PropertyName == nameof(ProcessorParameterVM.Value))
|
||||||
{
|
{
|
||||||
|
IsModified = true;
|
||||||
if (TryReportInvalidParameters())
|
if (TryReportInvalidParameters())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -623,9 +638,13 @@ namespace XplorePlane.ViewModels
|
|||||||
PreviewImage = null;
|
PreviewImage = null;
|
||||||
_currentFilePath = null;
|
_currentFilePath = null;
|
||||||
PipelineFileDisplayName = DefaultPipelineFileDisplayName;
|
PipelineFileDisplayName = DefaultPipelineFileDisplayName;
|
||||||
|
IsModified = false;
|
||||||
SetInfoStatus("已新建流水线");
|
SetInfoStatus("已新建流水线");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>供外部直接 await 的保存方法</summary>
|
||||||
|
public Task SaveAsync() => SavePipelineAsync();
|
||||||
|
|
||||||
private async Task SavePipelineAsync()
|
private async Task SavePipelineAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(PipelineName) || PipelineName.Length > 100)
|
if (string.IsNullOrWhiteSpace(PipelineName) || PipelineName.Length > 100)
|
||||||
@@ -674,6 +693,7 @@ namespace XplorePlane.ViewModels
|
|||||||
var model = BuildPipelineModel();
|
var model = BuildPipelineModel();
|
||||||
await _persistenceService.SaveAsync(model, filePath);
|
await _persistenceService.SaveAsync(model, filePath);
|
||||||
PipelineFileDisplayName = FormatPipelinePath(filePath);
|
PipelineFileDisplayName = FormatPipelinePath(filePath);
|
||||||
|
IsModified = false;
|
||||||
SetInfoStatus($"流水线已保存:{Path.GetFileName(filePath)}");
|
SetInfoStatus($"流水线已保存:{Path.GetFileName(filePath)}");
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
@@ -750,6 +770,7 @@ namespace XplorePlane.ViewModels
|
|||||||
UpdateExecutionRangeState();
|
UpdateExecutionRangeState();
|
||||||
|
|
||||||
_logger.Info("流水线已加载:{Name},节点数={Count}", model.Name, PipelineNodes.Count);
|
_logger.Info("流水线已加载:{Name},节点数={Count}", model.Name, PipelineNodes.Count);
|
||||||
|
IsModified = false;
|
||||||
SetInfoStatus($"已加载流水线:{model.Name}({PipelineNodes.Count} 个节点)");
|
SetInfoStatus($"已加载流水线:{model.Name}({PipelineNodes.Count} 个节点)");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ namespace XplorePlane.ViewModels
|
|||||||
private readonly IXpDataPathService _xpDataPathService;
|
private readonly IXpDataPathService _xpDataPathService;
|
||||||
private readonly CncEditorViewModel _cncEditorViewModel;
|
private readonly CncEditorViewModel _cncEditorViewModel;
|
||||||
private readonly CncPageView _cncPageView;
|
private readonly CncPageView _cncPageView;
|
||||||
|
private readonly PipelineEditorViewModel _pipelineEditorViewModel;
|
||||||
|
private readonly PipelineEditorView _pipelineEditorView;
|
||||||
|
|
||||||
public string LicenseInfo
|
public string LicenseInfo
|
||||||
{
|
{
|
||||||
@@ -212,6 +214,8 @@ namespace XplorePlane.ViewModels
|
|||||||
_xpDataPathService = xpDataPathService ?? throw new ArgumentNullException(nameof(xpDataPathService));
|
_xpDataPathService = xpDataPathService ?? throw new ArgumentNullException(nameof(xpDataPathService));
|
||||||
_cncEditorViewModel = _containerProvider.Resolve<CncEditorViewModel>();
|
_cncEditorViewModel = _containerProvider.Resolve<CncEditorViewModel>();
|
||||||
_cncPageView = new CncPageView { DataContext = _cncEditorViewModel };
|
_cncPageView = new CncPageView { DataContext = _cncEditorViewModel };
|
||||||
|
_pipelineEditorViewModel = _containerProvider.Resolve<PipelineEditorViewModel>();
|
||||||
|
_pipelineEditorView = new PipelineEditorView { DataContext = _pipelineEditorViewModel };
|
||||||
|
|
||||||
_mainViewportService.StateChanged += OnMainViewportStateChanged;
|
_mainViewportService.StateChanged += OnMainViewportStateChanged;
|
||||||
_cncEditorViewModel.PropertyChanged += (s, e) =>
|
_cncEditorViewModel.PropertyChanged += (s, e) =>
|
||||||
@@ -310,7 +314,7 @@ namespace XplorePlane.ViewModels
|
|||||||
OpenRealTimeLogViewerCommand = new DelegateCommand(ExecuteOpenRealTimeLogViewer);
|
OpenRealTimeLogViewerCommand = new DelegateCommand(ExecuteOpenRealTimeLogViewer);
|
||||||
UseLiveDetectorSourceCommand = new DelegateCommand(ExecuteUseLiveDetectorSource);
|
UseLiveDetectorSourceCommand = new DelegateCommand(ExecuteUseLiveDetectorSource);
|
||||||
|
|
||||||
ImagePanelContent = new PipelineEditorView();
|
ImagePanelContent = _pipelineEditorView;
|
||||||
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
|
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
|
||||||
ImagePanelWidth = new GridLength(320);
|
ImagePanelWidth = new GridLength(320);
|
||||||
DataRootPath = _xpDataPathService.RootPath;
|
DataRootPath = _xpDataPathService.RootPath;
|
||||||
@@ -352,10 +356,31 @@ namespace XplorePlane.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteOpenCncEditor()
|
private void ExecuteOpenCncEditor()
|
||||||
|
{
|
||||||
|
_ = ExecuteOpenCncEditorAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ExecuteOpenCncEditorAsync()
|
||||||
{
|
{
|
||||||
if (_isCncEditorMode)
|
if (_isCncEditorMode)
|
||||||
{
|
{
|
||||||
ImagePanelContent = new PipelineEditorView();
|
// CNC → 普通模式:检查 CNC 程序是否有未保存修改
|
||||||
|
if (_cncEditorViewModel.IsModified)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show(
|
||||||
|
"CNC 程序有未保存的修改,是否保存?",
|
||||||
|
"未保存的修改",
|
||||||
|
MessageBoxButton.YesNoCancel,
|
||||||
|
MessageBoxImage.Warning);
|
||||||
|
|
||||||
|
if (result == MessageBoxResult.Cancel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result == MessageBoxResult.Yes)
|
||||||
|
await _cncEditorViewModel.SaveAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagePanelContent = _pipelineEditorView;
|
||||||
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
|
ViewportPanelWidth = new GridLength(1, GridUnitType.Star);
|
||||||
ImagePanelWidth = new GridLength(320);
|
ImagePanelWidth = new GridLength(320);
|
||||||
_isCncEditorMode = false;
|
_isCncEditorMode = false;
|
||||||
@@ -363,6 +388,22 @@ namespace XplorePlane.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 普通 → CNC 模式:检查流水线是否有未保存修改
|
||||||
|
if (_pipelineEditorViewModel.IsModified)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show(
|
||||||
|
"图像处理流水线有未保存的修改,是否保存?",
|
||||||
|
"未保存的修改",
|
||||||
|
MessageBoxButton.YesNoCancel,
|
||||||
|
MessageBoxImage.Warning);
|
||||||
|
|
||||||
|
if (result == MessageBoxResult.Cancel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result == MessageBoxResult.Yes)
|
||||||
|
await _pipelineEditorViewModel.SaveAsync();
|
||||||
|
}
|
||||||
|
|
||||||
ShowCncEditor();
|
ShowCncEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user