规范类名及命名空间名称
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using XP.ImageProcessing.RoiControl.Models;
|
||||
|
||||
namespace XP.ImageProcessing.RoiControl.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// 图像ROI画布控件,支持图像显示、ROI编辑、缩放和平移
|
||||
/// </summary>
|
||||
public class ImageROICanvas : Control
|
||||
{
|
||||
private Canvas? roiCanvas;
|
||||
private bool isDragging = false;
|
||||
private Point mouseDownPoint = new Point();
|
||||
private const double ZoomStep = 1.2;
|
||||
private const double MinZoom = 0.1;
|
||||
private const double MaxZoom = 10.0;
|
||||
|
||||
static ImageROICanvas()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageROICanvas),
|
||||
new FrameworkPropertyMetadata(typeof(ImageROICanvas)));
|
||||
}
|
||||
|
||||
public ImageROICanvas()
|
||||
{
|
||||
Loaded += OnLoaded;
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
roiCanvas = GetTemplateChild("PART_Canvas") as Canvas;
|
||||
}
|
||||
|
||||
#region Dependency Properties
|
||||
|
||||
public static readonly DependencyProperty ImageSourceProperty =
|
||||
DependencyProperty.Register(nameof(ImageSource), typeof(ImageSource), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(null, OnImageSourceChanged));
|
||||
|
||||
public ImageSource? ImageSource
|
||||
{
|
||||
get => (ImageSource?)GetValue(ImageSourceProperty);
|
||||
set => SetValue(ImageSourceProperty, value);
|
||||
}
|
||||
|
||||
private static void OnImageSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var control = (ImageROICanvas)d;
|
||||
if (e.NewValue is BitmapSource bitmap && control.roiCanvas != null)
|
||||
{
|
||||
control.ImageWidth = bitmap.PixelWidth;
|
||||
control.ImageHeight = bitmap.PixelHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ROIItemsProperty =
|
||||
DependencyProperty.Register(nameof(ROIItems), typeof(ObservableCollection<ROIShape>), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public ObservableCollection<ROIShape>? ROIItems
|
||||
{
|
||||
get => (ObservableCollection<ROIShape>?)GetValue(ROIItemsProperty);
|
||||
set => SetValue(ROIItemsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ZoomScaleProperty =
|
||||
DependencyProperty.Register(nameof(ZoomScale), typeof(double), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(1.0));
|
||||
|
||||
public double ZoomScale
|
||||
{
|
||||
get => (double)GetValue(ZoomScaleProperty);
|
||||
set => SetValue(ZoomScaleProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ZoomCenterProperty =
|
||||
DependencyProperty.Register(nameof(ZoomCenter), typeof(Point), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(new Point()));
|
||||
|
||||
public Point ZoomCenter
|
||||
{
|
||||
get => (Point)GetValue(ZoomCenterProperty);
|
||||
set => SetValue(ZoomCenterProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PanningOffsetXProperty =
|
||||
DependencyProperty.Register(nameof(PanningOffsetX), typeof(double), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(0.0));
|
||||
|
||||
public double PanningOffsetX
|
||||
{
|
||||
get => (double)GetValue(PanningOffsetXProperty);
|
||||
set => SetValue(PanningOffsetXProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty PanningOffsetYProperty =
|
||||
DependencyProperty.Register(nameof(PanningOffsetY), typeof(double), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(0.0));
|
||||
|
||||
public double PanningOffsetY
|
||||
{
|
||||
get => (double)GetValue(PanningOffsetYProperty);
|
||||
set => SetValue(PanningOffsetYProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ImageWidthProperty =
|
||||
DependencyProperty.Register(nameof(ImageWidth), typeof(double), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(800.0));
|
||||
|
||||
public double ImageWidth
|
||||
{
|
||||
get => (double)GetValue(ImageWidthProperty);
|
||||
set => SetValue(ImageWidthProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ImageHeightProperty =
|
||||
DependencyProperty.Register(nameof(ImageHeight), typeof(double), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(600.0));
|
||||
|
||||
public double ImageHeight
|
||||
{
|
||||
get => (double)GetValue(ImageHeightProperty);
|
||||
set => SetValue(ImageHeightProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedROIProperty =
|
||||
DependencyProperty.Register(nameof(SelectedROI), typeof(ROIShape), typeof(ImageROICanvas),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
public ROIShape? SelectedROI
|
||||
{
|
||||
get => (ROIShape?)GetValue(SelectedROIProperty);
|
||||
set => SetValue(SelectedROIProperty, value);
|
||||
}
|
||||
|
||||
#endregion Dependency Properties
|
||||
|
||||
#region Mouse Events
|
||||
|
||||
protected override void OnMouseWheel(MouseWheelEventArgs e)
|
||||
{
|
||||
base.OnMouseWheel(e);
|
||||
|
||||
Point mousePos = e.GetPosition(this);
|
||||
|
||||
if (e.Delta > 0)
|
||||
{
|
||||
ZoomIn(mousePos);
|
||||
}
|
||||
else
|
||||
{
|
||||
ZoomOut(mousePos);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseLeftButtonDown(e);
|
||||
mouseDownPoint = e.GetPosition(this);
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
Point mousePoint = e.GetPosition(this);
|
||||
double mouseMoveLength = (mousePoint - mouseDownPoint).Length;
|
||||
|
||||
if (mouseMoveLength > 10 / ZoomScale)
|
||||
{
|
||||
isDragging = true;
|
||||
PanningOffsetX += mousePoint.X - mouseDownPoint.X;
|
||||
PanningOffsetY += mousePoint.Y - mouseDownPoint.Y;
|
||||
mouseDownPoint = mousePoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
|
||||
{
|
||||
base.OnMouseLeftButtonUp(e);
|
||||
|
||||
if (!isDragging)
|
||||
{
|
||||
// 处理点击事件(如添加多边形顶点)
|
||||
Point clickPoint = e.GetPosition(roiCanvas);
|
||||
OnCanvasClicked(clickPoint);
|
||||
}
|
||||
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
#endregion Mouse Events
|
||||
|
||||
#region Zoom Methods
|
||||
|
||||
public void ZoomIn(Point center)
|
||||
{
|
||||
double newZoom = ZoomScale * ZoomStep;
|
||||
if (newZoom <= MaxZoom)
|
||||
{
|
||||
ZoomCenter = center;
|
||||
ZoomScale = newZoom;
|
||||
}
|
||||
}
|
||||
|
||||
public void ZoomOut(Point center)
|
||||
{
|
||||
double newZoom = ZoomScale / ZoomStep;
|
||||
if (newZoom >= MinZoom)
|
||||
{
|
||||
ZoomCenter = center;
|
||||
ZoomScale = newZoom;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetZoom()
|
||||
{
|
||||
ZoomScale = 1.0;
|
||||
PanningOffsetX = 0;
|
||||
PanningOffsetY = 0;
|
||||
ZoomCenter = new Point();
|
||||
}
|
||||
|
||||
#endregion Zoom Methods
|
||||
|
||||
#region Events
|
||||
|
||||
public static readonly RoutedEvent CanvasClickedEvent =
|
||||
EventManager.RegisterRoutedEvent(nameof(CanvasClicked), RoutingStrategy.Bubble,
|
||||
typeof(RoutedEventHandler), typeof(ImageROICanvas));
|
||||
|
||||
public event RoutedEventHandler CanvasClicked
|
||||
{
|
||||
add { AddHandler(CanvasClickedEvent, value); }
|
||||
remove { RemoveHandler(CanvasClickedEvent, value); }
|
||||
}
|
||||
|
||||
protected virtual void OnCanvasClicked(Point position)
|
||||
{
|
||||
var args = new CanvasClickedEventArgs(CanvasClickedEvent, position);
|
||||
RaiseEvent(args);
|
||||
}
|
||||
|
||||
#endregion Events
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画布点击事件参数
|
||||
/// </summary>
|
||||
public class CanvasClickedEventArgs : RoutedEventArgs
|
||||
{
|
||||
public Point Position { get; }
|
||||
|
||||
public CanvasClickedEventArgs(RoutedEvent routedEvent, Point position) : base(routedEvent)
|
||||
{
|
||||
Position = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user