From 26a0f5bf0033ade42921d04cbda37e7d0e69a78e Mon Sep 17 00:00:00 2001 From: "wei.lw.li" Date: Tue, 21 Jul 2026 11:46:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B5=8B=E9=87=8F?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB=E5=90=8E?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E8=93=9D=E8=89=B2=E4=B8=8D=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SetActiveMeasurementTool改为toggle逻辑支持取消激活;ViewportPanelView测量完成后发布None事件;MainViewModel订阅事件自动重置按钮状态;Cleanup中反订阅防止内存泄漏 --- XplorePlane/ViewModels/Main/MainViewModel.cs | 47 ++++++++++++++++--- .../Views/Main/ViewportPanelView.xaml.cs | 3 ++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/XplorePlane/ViewModels/Main/MainViewModel.cs b/XplorePlane/ViewModels/Main/MainViewModel.cs index e0cb7231..9db41b01 100644 --- a/XplorePlane/ViewModels/Main/MainViewModel.cs +++ b/XplorePlane/ViewModels/Main/MainViewModel.cs @@ -67,6 +67,7 @@ namespace XplorePlane.ViewModels.Main private SubscriptionToken _addPipelineToCncToken; private SubscriptionToken _provideCaptureTargetToken; private SubscriptionToken _roleChangedToken; + private SubscriptionToken _measurementToolToken; private PropertyChangedEventHandler _cncPropertyChangedHandler; private EventHandler _cncRunCanExecuteChangedHandler; private EventHandler _cncStopCanExecuteChangedHandler; @@ -463,6 +464,8 @@ namespace XplorePlane.ViewModels.Main _eventAggregator.GetEvent().Unsubscribe(_provideCaptureTargetToken); if (_roleChangedToken != null) _eventAggregator.GetEvent().Unsubscribe(_roleChangedToken); + if (_measurementToolToken != null) + _eventAggregator.GetEvent().Unsubscribe(_measurementToolToken); _pipelinePreviewToken = null; _whiteBackgroundRoiToken = null; @@ -470,6 +473,7 @@ namespace XplorePlane.ViewModels.Main _addPipelineToCncToken = null; _provideCaptureTargetToken = null; _roleChangedToken = null; + _measurementToolToken = null; _logger.Info("MainViewModel 资源已清理"); } @@ -642,6 +646,10 @@ namespace XplorePlane.ViewModels.Main _addPipelineToCncToken = _eventAggregator.GetEvent() .Subscribe(OnAddPipelineToCncRequested, ThreadOption.UIThread); + // 订阅 MeasurementToolEvent,接收来自 View 层的测量完成/取消通知,自动重置按钮激活状态 + _measurementToolToken = _eventAggregator.GetEvent() + .Subscribe(OnMeasurementToolEventReceived, ThreadOption.UIThread); + NavigationTree = new ObservableCollection(); NavigateHomeCommand = new DelegateCommand(OnNavigateHome); @@ -1395,9 +1403,16 @@ namespace XplorePlane.ViewModels.Main private void SetActiveMeasurementTool(MeasurementToolMode mode) { - if (_activeMeasurementToolMode == mode) return; + // 切换行为:点击已激活的工具按钮时取消激活 + if (_activeMeasurementToolMode == mode) + { + _activeMeasurementToolMode = MeasurementToolMode.None; + } + else + { + _activeMeasurementToolMode = mode; + } - _activeMeasurementToolMode = mode; RaisePropertyChanged(nameof(IsPointDistanceMeasureActive)); RaisePropertyChanged(nameof(IsPointLineDistanceMeasureActive)); RaisePropertyChanged(nameof(IsAngleMeasureActive)); @@ -1411,6 +1426,24 @@ namespace XplorePlane.ViewModels.Main SetActiveMeasurementTool(MeasurementToolMode.None); } + /// + /// 接收来自 View 层的 MeasurementToolEvent(如 MeasureCompleted 后自动重置), + /// 仅在收到 None 且当前模式非 None 时重置按钮激活状态。 + /// + private void OnMeasurementToolEventReceived(MeasurementToolMode mode) + { + // 只处理 None 通知(外部取消/完成),避免与自身发布的切换事件产生循环 + if (mode == MeasurementToolMode.None && _activeMeasurementToolMode != MeasurementToolMode.None) + { + _activeMeasurementToolMode = MeasurementToolMode.None; + RaisePropertyChanged(nameof(IsPointDistanceMeasureActive)); + RaisePropertyChanged(nameof(IsPointLineDistanceMeasureActive)); + RaisePropertyChanged(nameof(IsAngleMeasureActive)); + RaisePropertyChanged(nameof(IsThroughHoleFillRateMeasureActive)); + RaisePropertyChanged(nameof(IsBubbleMeasureActive)); + } + } + private void SetActiveBackgroundDefectMode(BackgroundDefectMode? mode) { if (_activeBackgroundDefectMode == mode) return; @@ -1440,7 +1473,7 @@ namespace XplorePlane.ViewModels.Main if (!CheckImageLoaded()) return; _logger.Info("Point distance measurement triggered."); SetActiveMeasurementTool(MeasurementToolMode.PointDistance); - _eventAggregator.GetEvent().Publish(MeasurementToolMode.PointDistance); + _eventAggregator.GetEvent().Publish(_activeMeasurementToolMode); } private void ExecutePointLineDistanceMeasure() @@ -1448,7 +1481,7 @@ namespace XplorePlane.ViewModels.Main if (!CheckImageLoaded()) return; _logger.Info("Point-line distance measurement triggered."); SetActiveMeasurementTool(MeasurementToolMode.PointLineDistance); - _eventAggregator.GetEvent().Publish(MeasurementToolMode.PointLineDistance); + _eventAggregator.GetEvent().Publish(_activeMeasurementToolMode); } private void ExecuteAngleMeasure() @@ -1456,7 +1489,7 @@ namespace XplorePlane.ViewModels.Main if (!CheckImageLoaded()) return; _logger.Info("Angle measurement triggered."); SetActiveMeasurementTool(MeasurementToolMode.Angle); - _eventAggregator.GetEvent().Publish(MeasurementToolMode.Angle); + _eventAggregator.GetEvent().Publish(_activeMeasurementToolMode); } private void ExecuteThroughHoleFillRateMeasure() @@ -1464,7 +1497,7 @@ namespace XplorePlane.ViewModels.Main if (!CheckImageLoaded()) return; _logger.Info("Through-hole fill-rate measurement triggered."); SetActiveMeasurementTool(MeasurementToolMode.ThroughHoleFillRate); - _eventAggregator.GetEvent().Publish(MeasurementToolMode.ThroughHoleFillRate); + _eventAggregator.GetEvent().Publish(_activeMeasurementToolMode); } private void ExecuteBgaDetection() @@ -1507,7 +1540,7 @@ namespace XplorePlane.ViewModels.Main // Enter bubble measurement mode. SetActiveMeasurementTool(MeasurementToolMode.BubbleMeasure); - _eventAggregator.GetEvent().Publish(MeasurementToolMode.BubbleMeasure); + _eventAggregator.GetEvent().Publish(_activeMeasurementToolMode); // Open the tool panel. _windowLauncher.ShowOrActivateVisible( diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs index 3fc2d3d7..922bcbc9 100644 --- a/XplorePlane/Views/Main/ViewportPanelView.xaml.cs +++ b/XplorePlane/Views/Main/ViewportPanelView.xaml.cs @@ -196,6 +196,9 @@ namespace XplorePlane.Views.Main { ExecuteEdgeLineFitProcessor(args.P1, args.P2); } + + // 测量完成后自动取消激活状态,使工具栏按钮恢复默认色 + _eventAggregator?.GetEvent().Publish(MeasurementToolMode.None); } }; RoiCanvas.MeasureStatusChanged += (s, e) =>