修复实时模式下图像预览区仍可拖动的问题;非实时模式下鼠标跟随蓝色十字线功能
This commit is contained in:
@@ -190,6 +190,20 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
||||
set => SetValue(IsWheelZoomEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否允许拖动画布平移图像(默认允许)。
|
||||
/// 实时图像显示过程中可设为 false 以禁止图像拖动。
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
/// </summary>
|
||||
public bool IsWheelZoomEnabled => !_isRealtimeEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// 是否允许拖动图像:实时显示过程中禁用,停止实时后可拖动。
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
@@ -31,10 +31,11 @@
|
||||
Text="实时图像" />
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="1">
|
||||
<Grid Grid.Row="1" x:Name="ImageAreaGrid">
|
||||
<roi:PolygonRoiCanvas
|
||||
x:Name="RoiCanvas"
|
||||
ImageSource="{Binding ImageSource}"
|
||||
IsImagePanEnabled="{Binding IsImagePanEnabled}"
|
||||
IsWheelZoomEnabled="{Binding IsWheelZoomEnabled}"
|
||||
ScaleBarMmPerPixel="0.139"
|
||||
ShowScaleBar="{Binding DataContext.IsScaleBarVisible, RelativeSource={RelativeSource AncestorType=Window}}">
|
||||
@@ -66,6 +67,11 @@
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<!-- 鼠标跟随蓝色十字线叠加层(实时关闭时显示) -->
|
||||
<Canvas x:Name="MouseCrosshairOverlay"
|
||||
IsHitTestVisible="False"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<!-- 灰度直方图叠加层 -->
|
||||
<histogram:ImageHistogramControl
|
||||
x:Name="HistogramOverlay"
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace XplorePlane.Views
|
||||
public ViewportPanelView()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeMouseCrosshair();
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
AttachHistogramViewModel(DataContext as INotifyPropertyChanged);
|
||||
Loaded += (_, _) => UpdateHistogramFromCurrentImage();
|
||||
@@ -568,6 +569,88 @@ namespace XplorePlane.Views
|
||||
|
||||
#endregion
|
||||
|
||||
#region 鼠标跟随蓝色十字线
|
||||
|
||||
private System.Windows.Shapes.Line _mouseCrosshairH;
|
||||
private System.Windows.Shapes.Line _mouseCrosshairV;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化鼠标跟随十字线(在构造函数中调用)。
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当 IsRealtimeEnabled 变化时,隐藏鼠标十字线(开启实时后不再显示)。
|
||||
/// </summary>
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user