diff --git a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs
index 3e7460b0..d5267d5a 100644
--- a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs
+++ b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs
@@ -190,6 +190,20 @@ namespace XP.ImageProcessing.RoiControl.Controls
set => SetValue(IsWheelZoomEnabledProperty, value);
}
+ ///
+ /// 是否允许拖动画布平移图像(默认允许)。
+ /// 实时图像显示过程中可设为 false 以禁止图像拖动。
+ ///
+ public static readonly DependencyProperty IsImagePanEnabledProperty =
+ DependencyProperty.Register(nameof(IsImagePanEnabled), typeof(bool), typeof(PolygonRoiCanvas),
+ new PropertyMetadata(true));
+
+ public bool IsImagePanEnabled
+ {
+ get => (bool)GetValue(IsImagePanEnabledProperty);
+ set => SetValue(IsImagePanEnabledProperty, value);
+ }
+
public static readonly DependencyProperty PanOffsetXProperty =
DependencyProperty.Register(nameof(PanOffsetX), typeof(double), typeof(PolygonRoiCanvas),
new PropertyMetadata(0.0, OnPanOffsetChanged));
@@ -2355,6 +2369,10 @@ namespace XP.ImageProcessing.RoiControl.Controls
lastMousePosition = e.GetPosition(imageDisplayGrid);
isDragging = false;
+ if (!IsImagePanEnabled)
+ {
+ return;
+ }
mainCanvas.CaptureMouse();
}
@@ -2447,7 +2465,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
return;
}
- if (e.LeftButton == MouseButtonState.Pressed && mainCanvas.IsMouseCaptured)
+ if (IsImagePanEnabled && e.LeftButton == MouseButtonState.Pressed && mainCanvas.IsMouseCaptured)
{
Point currentPosition = e.GetPosition(imageDisplayGrid);
Vector delta = currentPosition - lastMousePosition;
@@ -2733,4 +2751,4 @@ namespace XP.ImageProcessing.RoiControl.Controls
#endregion Events
}
-}
\ No newline at end of file
+}
diff --git a/XplorePlane/ViewModels/Main/ViewportPanelViewModel.cs b/XplorePlane/ViewModels/Main/ViewportPanelViewModel.cs
index b5180e37..d926a43a 100644
--- a/XplorePlane/ViewModels/Main/ViewportPanelViewModel.cs
+++ b/XplorePlane/ViewModels/Main/ViewportPanelViewModel.cs
@@ -131,6 +131,7 @@ using XP.Common.Controls.ImageHistogram;
{
_mainViewportService.SetRealtimeDisplayEnabled(value);
RaisePropertyChanged(nameof(IsWheelZoomEnabled));
+ RaisePropertyChanged(nameof(IsImagePanEnabled));
}
}
}
@@ -140,6 +141,11 @@ using XP.Common.Controls.ImageHistogram;
///
public bool IsWheelZoomEnabled => !_isRealtimeEnabled;
+ ///
+ /// 是否允许拖动图像:实时显示过程中禁用,停止实时后可拖动。
+ ///
+ public bool IsImagePanEnabled => !_isRealtimeEnabled;
+
// Task 5.3: IsDetectorConnected property (read-only, private setter)
public bool IsDetectorConnected
{
@@ -322,6 +328,7 @@ using XP.Common.Controls.ImageHistogram;
_isRealtimeEnabled = _mainViewportService.IsRealtimeDisplayEnabled;
RaisePropertyChanged(nameof(IsRealtimeEnabled));
RaisePropertyChanged(nameof(IsWheelZoomEnabled));
+ RaisePropertyChanged(nameof(IsImagePanEnabled));
// Task 5.8: Sync _isCncRunning from service and raise IsAnimatedSwitchEnabled
_isCncRunning = _mainViewportService.IsCncRunning;
diff --git a/XplorePlane/Views/Main/ViewportPanelView.xaml b/XplorePlane/Views/Main/ViewportPanelView.xaml
index 7e892fc8..343bece3 100644
--- a/XplorePlane/Views/Main/ViewportPanelView.xaml
+++ b/XplorePlane/Views/Main/ViewportPanelView.xaml
@@ -31,10 +31,11 @@
Text="实时图像" />
-
+
@@ -66,6 +67,11 @@
IsHitTestVisible="False"
Visibility="Collapsed" />
+
+
+
UpdateHistogramFromCurrentImage();
@@ -568,6 +569,88 @@ namespace XplorePlane.Views
#endregion
+ #region 鼠标跟随蓝色十字线
+
+ private System.Windows.Shapes.Line _mouseCrosshairH;
+ private System.Windows.Shapes.Line _mouseCrosshairV;
+
+ ///
+ /// 初始化鼠标跟随十字线(在构造函数中调用)。
+ ///
+ private void InitializeMouseCrosshair()
+ {
+ var brush = new SolidColorBrush(Color.FromArgb(200, 0, 120, 255));
+ brush.Freeze();
+
+ _mouseCrosshairH = new System.Windows.Shapes.Line
+ {
+ Stroke = brush,
+ StrokeThickness = 1,
+ IsHitTestVisible = false,
+ SnapsToDevicePixels = true
+ };
+
+ _mouseCrosshairV = new System.Windows.Shapes.Line
+ {
+ Stroke = brush,
+ StrokeThickness = 1,
+ IsHitTestVisible = false,
+ SnapsToDevicePixels = true
+ };
+
+ MouseCrosshairOverlay.Children.Add(_mouseCrosshairH);
+ MouseCrosshairOverlay.Children.Add(_mouseCrosshairV);
+
+ // 在图像区域 Grid 上监听鼠标事件
+ ImageAreaGrid.MouseMove += OnImageAreaMouseMove;
+ ImageAreaGrid.MouseLeave += OnImageAreaMouseLeave;
+ }
+
+ private void OnImageAreaMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
+ {
+ var vm = DataContext as ViewportPanelViewModel;
+ if (vm == null || vm.IsRealtimeEnabled)
+ {
+ MouseCrosshairOverlay.Visibility = Visibility.Collapsed;
+ return;
+ }
+
+ MouseCrosshairOverlay.Visibility = Visibility.Visible;
+
+ var pos = e.GetPosition(ImageAreaGrid);
+ double w = ImageAreaGrid.ActualWidth;
+ double h = ImageAreaGrid.ActualHeight;
+
+ _mouseCrosshairH.X1 = 0;
+ _mouseCrosshairH.Y1 = pos.Y;
+ _mouseCrosshairH.X2 = w;
+ _mouseCrosshairH.Y2 = pos.Y;
+
+ _mouseCrosshairV.X1 = pos.X;
+ _mouseCrosshairV.Y1 = 0;
+ _mouseCrosshairV.X2 = pos.X;
+ _mouseCrosshairV.Y2 = h;
+ }
+
+ private void OnImageAreaMouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
+ {
+ MouseCrosshairOverlay.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// 当 IsRealtimeEnabled 变化时,隐藏鼠标十字线(开启实时后不再显示)。
+ ///
+ private void OnRealtimeStateChangedForMouseCrosshair()
+ {
+ var vm = DataContext as ViewportPanelViewModel;
+ if (vm != null && vm.IsRealtimeEnabled)
+ {
+ MouseCrosshairOverlay.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ #endregion
+
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
AttachHistogramViewModel(e.NewValue as INotifyPropertyChanged);
@@ -596,6 +679,11 @@ namespace XplorePlane.Views
{
UpdateHistogramFromCurrentImage();
}
+
+ if (e.PropertyName == nameof(ViewportPanelViewModel.IsRealtimeEnabled))
+ {
+ OnRealtimeStateChangedForMouseCrosshair();
+ }
}
private void UpdateHistogramFromCurrentImage()