修复实时模式下图像预览区仍可拖动的问题;非实时模式下鼠标跟随蓝色十字线功能
This commit is contained in:
@@ -190,6 +190,20 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
|||||||
set => SetValue(IsWheelZoomEnabledProperty, value);
|
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 =
|
public static readonly DependencyProperty PanOffsetXProperty =
|
||||||
DependencyProperty.Register(nameof(PanOffsetX), typeof(double), typeof(PolygonRoiCanvas),
|
DependencyProperty.Register(nameof(PanOffsetX), typeof(double), typeof(PolygonRoiCanvas),
|
||||||
new PropertyMetadata(0.0, OnPanOffsetChanged));
|
new PropertyMetadata(0.0, OnPanOffsetChanged));
|
||||||
@@ -2355,6 +2369,10 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
|||||||
|
|
||||||
lastMousePosition = e.GetPosition(imageDisplayGrid);
|
lastMousePosition = e.GetPosition(imageDisplayGrid);
|
||||||
isDragging = false;
|
isDragging = false;
|
||||||
|
if (!IsImagePanEnabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
mainCanvas.CaptureMouse();
|
mainCanvas.CaptureMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2447,7 +2465,7 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.LeftButton == MouseButtonState.Pressed && mainCanvas.IsMouseCaptured)
|
if (IsImagePanEnabled && e.LeftButton == MouseButtonState.Pressed && mainCanvas.IsMouseCaptured)
|
||||||
{
|
{
|
||||||
Point currentPosition = e.GetPosition(imageDisplayGrid);
|
Point currentPosition = e.GetPosition(imageDisplayGrid);
|
||||||
Vector delta = currentPosition - lastMousePosition;
|
Vector delta = currentPosition - lastMousePosition;
|
||||||
@@ -2733,4 +2751,4 @@ namespace XP.ImageProcessing.RoiControl.Controls
|
|||||||
|
|
||||||
#endregion Events
|
#endregion Events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ using XP.Common.Controls.ImageHistogram;
|
|||||||
{
|
{
|
||||||
_mainViewportService.SetRealtimeDisplayEnabled(value);
|
_mainViewportService.SetRealtimeDisplayEnabled(value);
|
||||||
RaisePropertyChanged(nameof(IsWheelZoomEnabled));
|
RaisePropertyChanged(nameof(IsWheelZoomEnabled));
|
||||||
|
RaisePropertyChanged(nameof(IsImagePanEnabled));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,6 +141,11 @@ using XP.Common.Controls.ImageHistogram;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsWheelZoomEnabled => !_isRealtimeEnabled;
|
public bool IsWheelZoomEnabled => !_isRealtimeEnabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否允许拖动图像:实时显示过程中禁用,停止实时后可拖动。
|
||||||
|
/// </summary>
|
||||||
|
public bool IsImagePanEnabled => !_isRealtimeEnabled;
|
||||||
|
|
||||||
// Task 5.3: IsDetectorConnected property (read-only, private setter)
|
// Task 5.3: IsDetectorConnected property (read-only, private setter)
|
||||||
public bool IsDetectorConnected
|
public bool IsDetectorConnected
|
||||||
{
|
{
|
||||||
@@ -322,6 +328,7 @@ using XP.Common.Controls.ImageHistogram;
|
|||||||
_isRealtimeEnabled = _mainViewportService.IsRealtimeDisplayEnabled;
|
_isRealtimeEnabled = _mainViewportService.IsRealtimeDisplayEnabled;
|
||||||
RaisePropertyChanged(nameof(IsRealtimeEnabled));
|
RaisePropertyChanged(nameof(IsRealtimeEnabled));
|
||||||
RaisePropertyChanged(nameof(IsWheelZoomEnabled));
|
RaisePropertyChanged(nameof(IsWheelZoomEnabled));
|
||||||
|
RaisePropertyChanged(nameof(IsImagePanEnabled));
|
||||||
|
|
||||||
// Task 5.8: Sync _isCncRunning from service and raise IsAnimatedSwitchEnabled
|
// Task 5.8: Sync _isCncRunning from service and raise IsAnimatedSwitchEnabled
|
||||||
_isCncRunning = _mainViewportService.IsCncRunning;
|
_isCncRunning = _mainViewportService.IsCncRunning;
|
||||||
|
|||||||
@@ -31,10 +31,11 @@
|
|||||||
Text="实时图像" />
|
Text="实时图像" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1" x:Name="ImageAreaGrid">
|
||||||
<roi:PolygonRoiCanvas
|
<roi:PolygonRoiCanvas
|
||||||
x:Name="RoiCanvas"
|
x:Name="RoiCanvas"
|
||||||
ImageSource="{Binding ImageSource}"
|
ImageSource="{Binding ImageSource}"
|
||||||
|
IsImagePanEnabled="{Binding IsImagePanEnabled}"
|
||||||
IsWheelZoomEnabled="{Binding IsWheelZoomEnabled}"
|
IsWheelZoomEnabled="{Binding IsWheelZoomEnabled}"
|
||||||
ScaleBarMmPerPixel="0.139"
|
ScaleBarMmPerPixel="0.139"
|
||||||
ShowScaleBar="{Binding DataContext.IsScaleBarVisible, RelativeSource={RelativeSource AncestorType=Window}}">
|
ShowScaleBar="{Binding DataContext.IsScaleBarVisible, RelativeSource={RelativeSource AncestorType=Window}}">
|
||||||
@@ -66,6 +67,11 @@
|
|||||||
IsHitTestVisible="False"
|
IsHitTestVisible="False"
|
||||||
Visibility="Collapsed" />
|
Visibility="Collapsed" />
|
||||||
|
|
||||||
|
<!-- 鼠标跟随蓝色十字线叠加层(实时关闭时显示) -->
|
||||||
|
<Canvas x:Name="MouseCrosshairOverlay"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
Visibility="Collapsed" />
|
||||||
|
|
||||||
<!-- 灰度直方图叠加层 -->
|
<!-- 灰度直方图叠加层 -->
|
||||||
<histogram:ImageHistogramControl
|
<histogram:ImageHistogramControl
|
||||||
x:Name="HistogramOverlay"
|
x:Name="HistogramOverlay"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace XplorePlane.Views
|
|||||||
public ViewportPanelView()
|
public ViewportPanelView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
InitializeMouseCrosshair();
|
||||||
DataContextChanged += OnDataContextChanged;
|
DataContextChanged += OnDataContextChanged;
|
||||||
AttachHistogramViewModel(DataContext as INotifyPropertyChanged);
|
AttachHistogramViewModel(DataContext as INotifyPropertyChanged);
|
||||||
Loaded += (_, _) => UpdateHistogramFromCurrentImage();
|
Loaded += (_, _) => UpdateHistogramFromCurrentImage();
|
||||||
@@ -568,6 +569,88 @@ namespace XplorePlane.Views
|
|||||||
|
|
||||||
#endregion
|
#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)
|
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
AttachHistogramViewModel(e.NewValue as INotifyPropertyChanged);
|
AttachHistogramViewModel(e.NewValue as INotifyPropertyChanged);
|
||||||
@@ -596,6 +679,11 @@ namespace XplorePlane.Views
|
|||||||
{
|
{
|
||||||
UpdateHistogramFromCurrentImage();
|
UpdateHistogramFromCurrentImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.PropertyName == nameof(ViewportPanelViewModel.IsRealtimeEnabled))
|
||||||
|
{
|
||||||
|
OnRealtimeStateChangedForMouseCrosshair();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateHistogramFromCurrentImage()
|
private void UpdateHistogramFromCurrentImage()
|
||||||
|
|||||||
Reference in New Issue
Block a user