CNC运行与底部状态栏提醒
This commit is contained in:
@@ -42,6 +42,9 @@ namespace XplorePlane.ViewModels.Cnc
|
||||
private bool _pendingInsertAfterAnchor;
|
||||
private CancellationTokenSource _cts;
|
||||
private bool _isRunning;
|
||||
private string _statusMessage = "就绪";
|
||||
private string _executionError;
|
||||
private bool _hasExecutionError;
|
||||
|
||||
public CncEditorViewModel(
|
||||
ICncProgramService cncProgramService,
|
||||
@@ -159,6 +162,24 @@ namespace XplorePlane.ViewModels.Cnc
|
||||
}
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get => _statusMessage;
|
||||
private set => SetProperty(ref _statusMessage, value);
|
||||
}
|
||||
|
||||
public string ExecutionError
|
||||
{
|
||||
get => _executionError;
|
||||
private set => SetProperty(ref _executionError, value);
|
||||
}
|
||||
|
||||
public bool HasExecutionError
|
||||
{
|
||||
get => _hasExecutionError;
|
||||
private set => SetProperty(ref _hasExecutionError, value);
|
||||
}
|
||||
|
||||
public DelegateCommand InsertReferencePointCommand { get; }
|
||||
public DelegateCommand InsertSaveNodeWithImageCommand { get; }
|
||||
public DelegateCommand InsertSaveNodeCommand { get; }
|
||||
@@ -435,14 +456,28 @@ namespace XplorePlane.ViewModels.Cnc
|
||||
{
|
||||
_cts = new CancellationTokenSource();
|
||||
IsRunning = true;
|
||||
HasExecutionError = false;
|
||||
ExecutionError = null;
|
||||
StatusMessage = $"正在执行:{_currentProgram?.Name ?? "程序"}(共 {_currentProgram?.Nodes?.Count ?? 0} 个节点)";
|
||||
try
|
||||
{
|
||||
var progress = new Progress<CncNodeExecutionProgress>(OnExecutionProgress);
|
||||
await _cncExecutionService.ExecuteAsync(_currentProgram, progress, _cts.Token);
|
||||
if (_cts.IsCancellationRequested)
|
||||
StatusMessage = "执行已停止";
|
||||
else
|
||||
StatusMessage = $"执行完成:{_currentProgram?.Name}";
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
StatusMessage = "执行已取消";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, "CNC execution failed");
|
||||
ExecutionError = ex.Message;
|
||||
HasExecutionError = true;
|
||||
StatusMessage = $"执行失败:{ex.Message}";
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -462,7 +497,17 @@ namespace XplorePlane.ViewModels.Cnc
|
||||
{
|
||||
var nodeVm = Nodes.FirstOrDefault(n => n.Id == progress.NodeId);
|
||||
if (nodeVm != null)
|
||||
{
|
||||
nodeVm.ExecutionState = progress.State;
|
||||
if (progress.State == NodeExecutionState.Running)
|
||||
StatusMessage = $"正在执行节点:{nodeVm.Name}({nodeVm.Index + 1}/{_currentProgram?.Nodes?.Count ?? 0})";
|
||||
else if (progress.State == NodeExecutionState.Failed)
|
||||
{
|
||||
HasExecutionError = true;
|
||||
ExecutionError = $"节点 [{nodeVm.Name}] 执行失败";
|
||||
StatusMessage = $"错误:节点 [{nodeVm.Name}] 执行失败";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetAllNodeStates()
|
||||
|
||||
@@ -57,6 +57,20 @@ namespace XplorePlane.ViewModels
|
||||
_cncPageView = new CncPageView { DataContext = _cncEditorViewModel };
|
||||
|
||||
_mainViewportService.StateChanged += OnMainViewportStateChanged;
|
||||
_cncEditorViewModel.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(CncEditorViewModel.StatusMessage))
|
||||
RaisePropertyChanged(nameof(CncStatusMessage));
|
||||
else if (e.PropertyName == nameof(CncEditorViewModel.HasExecutionError))
|
||||
RaisePropertyChanged(nameof(CncHasExecutionError));
|
||||
else if (e.PropertyName == nameof(CncEditorViewModel.IsRunning))
|
||||
{
|
||||
RunCncCommand.RaiseCanExecuteChanged();
|
||||
StopCncCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
};
|
||||
_cncEditorViewModel.RunCncCommand.CanExecuteChanged += (s, e) => RunCncCommand.RaiseCanExecuteChanged();
|
||||
_cncEditorViewModel.StopCncCommand.CanExecuteChanged += (s, e) => StopCncCommand.RaiseCanExecuteChanged();
|
||||
|
||||
NavigationTree = new ObservableCollection<object>();
|
||||
|
||||
@@ -87,8 +101,12 @@ namespace XplorePlane.ViewModels
|
||||
InsertSaveNodeCommand = new DelegateCommand(() => ExecuteCncEditorAction(vm => vm.InsertSaveNodeCommand.Execute()));
|
||||
InsertPauseDialogCommand = new DelegateCommand(() => ExecuteCncEditorAction(vm => vm.InsertPauseDialogCommand.Execute()));
|
||||
InsertWaitDelayCommand = new DelegateCommand(() => ExecuteCncEditorAction(vm => vm.InsertWaitDelayCommand.Execute()));
|
||||
RunCncCommand = new DelegateCommand(() => ExecuteCncEditorAction(vm => vm.RunCncCommand.Execute()));
|
||||
StopCncCommand = new DelegateCommand(() => ExecuteCncEditorAction(vm => vm.StopCncCommand.Execute()));
|
||||
RunCncCommand = new DelegateCommand(
|
||||
() => ExecuteCncEditorAction(vm => vm.RunCncCommand.Execute()),
|
||||
() => _cncEditorViewModel.RunCncCommand.CanExecute());
|
||||
StopCncCommand = new DelegateCommand(
|
||||
() => ExecuteCncEditorAction(vm => vm.StopCncCommand.Execute()),
|
||||
() => _cncEditorViewModel.StopCncCommand.CanExecute());
|
||||
|
||||
PointDistanceMeasureCommand = new DelegateCommand(ExecutePointDistanceMeasure);
|
||||
PointLineDistanceMeasureCommand = new DelegateCommand(ExecutePointLineDistanceMeasure);
|
||||
@@ -121,6 +139,9 @@ namespace XplorePlane.ViewModels
|
||||
set => SetProperty(ref _licenseInfo, value);
|
||||
}
|
||||
|
||||
public string CncStatusMessage => _cncEditorViewModel.StatusMessage;
|
||||
public bool CncHasExecutionError => _cncEditorViewModel.HasExecutionError;
|
||||
|
||||
public ObservableCollection<object> NavigationTree { get; set; }
|
||||
|
||||
public DelegateCommand NavigateHomeCommand { get; set; }
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
<StackPanel>
|
||||
<telerik:RadRibbonButton
|
||||
telerik:ScreenTip.Title="运行"
|
||||
Command="{Binding RunCncCommand}"
|
||||
Size="Large"
|
||||
SmallImage="/Assets/Icons/run.png"
|
||||
Text="运行" />
|
||||
@@ -114,6 +115,7 @@
|
||||
<telerik:RadRibbonButton
|
||||
telerik:ScreenTip.Description="停止"
|
||||
telerik:ScreenTip.Title="停止"
|
||||
Command="{Binding StopCncCommand}"
|
||||
Size="Large"
|
||||
SmallImage="/Assets/Icons/stop.png"
|
||||
Text="停止" />
|
||||
@@ -554,7 +556,19 @@
|
||||
FontFamily="Microsoft YaHei UI"
|
||||
FontSize="11"
|
||||
Foreground="White"
|
||||
Text="就绪" />
|
||||
Text="{Binding CncStatusMessage}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CncHasExecutionError}" Value="True">
|
||||
<Setter Property="Foreground" Value="#FF9090" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
@@ -563,7 +577,7 @@
|
||||
FontFamily="Consolas"
|
||||
FontSize="11"
|
||||
Foreground="White"
|
||||
Text="x: 0 y: 0 RGB: 0 0 0" />
|
||||
Text="x: 0 y: 0" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
Reference in New Issue
Block a user