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