fix: 修复测量工具按钮点击后背景蓝色不恢复的问题

SetActiveMeasurementTool改为toggle逻辑支持取消激活;ViewportPanelView测量完成后发布None事件;MainViewModel订阅事件自动重置按钮状态;Cleanup中反订阅防止内存泄漏
This commit is contained in:
wei.lw.li
2026-07-21 11:46:01 +08:00
parent 65d742102a
commit 26a0f5bf00
2 changed files with 43 additions and 7 deletions
+40 -7
View File
@@ -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<ProvideCaptureTargetEvent>().Unsubscribe(_provideCaptureTargetToken);
if (_roleChangedToken != null)
_eventAggregator.GetEvent<RoleChangedEvent>().Unsubscribe(_roleChangedToken);
if (_measurementToolToken != null)
_eventAggregator.GetEvent<MeasurementToolEvent>().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<AddPipelineToCncRequestedEvent>()
.Subscribe(OnAddPipelineToCncRequested, ThreadOption.UIThread);
// 订阅 MeasurementToolEvent,接收来自 View 层的测量完成/取消通知,自动重置按钮激活状态
_measurementToolToken = _eventAggregator.GetEvent<MeasurementToolEvent>()
.Subscribe(OnMeasurementToolEventReceived, ThreadOption.UIThread);
NavigationTree = new ObservableCollection<object>();
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);
}
/// <summary>
/// 接收来自 View 层的 MeasurementToolEvent(如 MeasureCompleted 后自动重置),
/// 仅在收到 None 且当前模式非 None 时重置按钮激活状态。
/// </summary>
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<MeasurementToolEvent>().Publish(MeasurementToolMode.PointDistance);
_eventAggregator.GetEvent<MeasurementToolEvent>().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<MeasurementToolEvent>().Publish(MeasurementToolMode.PointLineDistance);
_eventAggregator.GetEvent<MeasurementToolEvent>().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<MeasurementToolEvent>().Publish(MeasurementToolMode.Angle);
_eventAggregator.GetEvent<MeasurementToolEvent>().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<MeasurementToolEvent>().Publish(MeasurementToolMode.ThroughHoleFillRate);
_eventAggregator.GetEvent<MeasurementToolEvent>().Publish(_activeMeasurementToolMode);
}
private void ExecuteBgaDetection()
@@ -1507,7 +1540,7 @@ namespace XplorePlane.ViewModels.Main
// Enter bubble measurement mode.
SetActiveMeasurementTool(MeasurementToolMode.BubbleMeasure);
_eventAggregator.GetEvent<MeasurementToolEvent>().Publish(MeasurementToolMode.BubbleMeasure);
_eventAggregator.GetEvent<MeasurementToolEvent>().Publish(_activeMeasurementToolMode);
// Open the tool panel.
_windowLauncher.ShowOrActivateVisible(
@@ -196,6 +196,9 @@ namespace XplorePlane.Views.Main
{
ExecuteEdgeLineFitProcessor(args.P1, args.P2);
}
// 测量完成后自动取消激活状态,使工具栏按钮恢复默认色
_eventAggregator?.GetEvent<MeasurementToolEvent>().Publish(MeasurementToolMode.None);
}
};
RoiCanvas.MeasureStatusChanged += (s, e) =>