一、创建基础的通用通知类和命令类
1.创建带有对象属性通知的抽象类BaseModel继承自INotifyPropertyChanged实现RiseProperty方法
/// <summary> /// 带有对象属性通知的抽象类 /// </summary> public abstract class BaseModel :INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void RiseProperty(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
2.创建命令对象类SimpleCommand继承自ICommand
/// <summary> /// 创建命令对象类 /// </summary> public class SimpleCommand : ICommand { public event EventHandler CanExecuteChanged; public Action<object> DoExecute { get; set; } public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { if (DoExecute != null) { DoExecute(parameter); } } }
二、使用ViewModel中的命令绘制矩形图像
1.创建矩形模型类RectangleModel继承自BaseModel
/// <summary> /// 矩形模型类 /// </summary> public class RectangleModel : BaseModel { private double _rectangleWidth; private double _rectangleHeight; private double _rectangleLeft; private double _rectangleTop; public double RectangleWidth { get { return _rectangleWidth; } set { _rectangleWidth = value; RiseProperty(nameof(RectangleWidth)); } } public double RectangleHeight { get { return _rectangleHeight; } set { _rectangleHeight = value; RiseProperty(nameof(RectangleHeight)); } } public double RectangleLeft { get { return _rectangleLeft; } set { _rectangleLeft = value; RiseProperty(nameof(RectangleLeft)); } } public double RectangleTop { get { return _rectangleTop; } set { _rectangleTop = value; RiseProperty(nameof(RectangleTop)); } } public RectangleModel() { RectangleWidth = 0; RectangleHeight = 0; RectangleLeft = 0; RectangleTop = 0; } public void InitRectangle() { RectangleWidth = 0; RectangleHeight = 0; RectangleLeft = 0; RectangleTop = 0; } }
2.在MainWindowViewModel中定义并初始化矩形类,并定义对应的鼠标按下,移动,弹起的命令
public RectangleModel RectModel { get; set; } = new RectangleModel(); public SimpleCommand MouseDownCommand { get; private set; } public SimpleCommand MouseMoveCommand { get; private set; } public SimpleCommand MouseUpCommand { get; private set; } public SimpleCommand DrawRectComand { get; private set; } public SimpleCommand DiscernComand { get; private set; } public MainWindowViewModel() { MouseDownCommand = new SimpleCommand { DoExecute = new Action<object>(MouseDown) }; MouseMoveCommand = new SimpleCommand { DoExecute = new Action<object>(MouseMove) }; MouseUpCommand = new SimpleCommand { DoExecute = new Action<object>(MouseUp) }; DrawRectComand = new SimpleCommand { DoExecute = new Action<object>(DrawRect) }; DiscernComand = new SimpleCommand { DoExecute = new Action<object>(DiscernAction) }; }
3.在xaml页面上增加canvas和相关的命令
<Canvas Name="MyCanvas" Background="Transparent"> <Rectangle Stroke="Red" Width="{Binding RectModel.RectangleWidth}" Height="{Binding RectModel.RectangleHeight}" Canvas.Left="{Binding RectModel.RectangleLeft}" Canvas.Top="{Binding RectModel.RectangleTop}" /> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDown"> <i:InvokeCommandAction Command="{Binding MouseDownCommand}" CommandParameter="{Binding ElementName=MyCanvas}" /> </i:EventTrigger> <i:EventTrigger EventName="MouseMove"> <i:InvokeCommandAction Command="{Binding MouseMoveCommand}" /> </i:EventTrigger> <i:EventTrigger EventName="MouseUp"> <i:InvokeCommandAction Command="{Binding MouseUpCommand}" /> </i:EventTrigger> </i:Interaction.Triggers> </Canvas>
将canvas中的事件转换为命令需使用动态库Microsoft.Xaml.Behaviors.Wpf,并在xaml中添加引用: xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
使用 <i:Interaction.Triggers>触发器添加<i:EventTrigger EventName="MouseDown">触发事件并绑定命令
<i:InvokeCommandAction Command="{Binding MouseDownCommand}" CommandParameter="{Binding ElementName=MyCanvas}" />
通过命令参数将canvs的名称传给命令
4.鼠标按下的命令执行逻辑
/// <summary> /// 鼠标按下的命令执行逻辑 /// </summary> /// <param name="obj"></param> /// <exception cref="NotImplementedException"></exception> private void MouseDown(object obj) { //按下鼠标左键时 if (Mouse.LeftButton == MouseButtonState.Pressed) { _hv_Hanlde = _controlWPF.HalconWindow; _myCanvas = obj as Canvas; //obj作为命令参数可转换为canvas类型 _startPoint = Mouse.GetPosition(_myCanvas); //获取鼠标在canvas中按下的位置坐标 // 获取窗口加载的图片部分对象 var imagePart = _controlWPF.HImagePart; // 获取图片与窗口的高度比 _k = imagePart.Height / _controlWPF.ActualHeight; // 获取图片部分在窗口的坐标 _tx = imagePart.X; _ty = imagePart.Y; // 如果缩放窗口,那么比例值肯定要变化 var hdp = DependencyPropertyDescriptor .FromProperty(HSmartWindowControlWPF.HImagePartProperty, typeof(HSmartWindowControlWPF)); hdp.AddValueChanged(_controlWPF, (o, e) => { imagePart = _controlWPF.HImagePart; // 获取图片与窗口的高度比 _k = imagePart.Height / _controlWPF.ActualHeight; // 获取图片部分在窗口的坐标 _tx = imagePart.X; _ty = imagePart.Y; }); } }
5.鼠标移动的命令逻辑
private void MouseMove(object obj) { if (Mouse.LeftButton == MouseButtonState.Pressed) { _endPoint = Mouse.GetPosition(_myCanvas); // 计算画矩形的长和高 var width = Math.Abs(_endPoint.X - _startPoint.X); var height = Math.Abs(_endPoint.Y - _startPoint.Y); // 设置矩形在Canvas上面的定位 var top = _startPoint.Y; var left = _startPoint.X; switch (_shapeType) { case ShapeType.Cricle: break; case ShapeType.Rectangle: // 设置属性的值 RectModel.RectangleWidth = width; RectModel.RectangleHeight = height; RectModel.RectangleLeft = left; RectModel.RectangleTop = top; // 把图像坐标转换为Halcon坐标 ConvertToHalconPoint(_startPoint.X, _startPoint.Y, _k, _tx, _ty, out double column, out double row); ConvertToHalconPoint(_endPoint.X, _endPoint.Y, _k, _tx, _ty, out double column1, out double row1); _row = row; _column = column; _row1 = row1; _column1 = column1; break; default: break; } } }
6. 鼠标松开的方法
/// <summary> /// 鼠标松开的方法 /// </summary> /// <param name="obj"></param> private void MouseUp(object obj) { if (DispImage != null && _myCanvas != null) { // 应该根据选择ROI类型绘制对应图像放到Halcon窗口上面 switch (_shapeType) { case ShapeType.Cricle: break; case ShapeType.Rectangle: var rectTuple = new HTuple[] { _row, _column, _row1, _column1 }; // 绘制矩形对象 var rect = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.RECTANGLE1, rectTuple); _roi = new NewDrawingObject { DrawingObject = rect, HTuples = rectTuple }; // 把矩形放到Halcon窗口 _hv_Hanlde.AttachDrawingObjectToWindow(rect); break; default: break; } // 设置ROI区域的拖拽及缩放事件 if (_roi!= null) { _roi.DrawingObject.OnDrag(DragCallbackClass); _roi.DrawingObject.OnResize(ResizeCallbackClass); } _myCanvas.Visibility = Visibility.Collapsed; RectModel.InitRectangle(); } }
7.把图像坐标转换为Halcon坐标系
private void ConvertToHalconPoint(double x, double y, double k, double tx, double ty, out double row, out double column) { row = k * x + tx; column = k * y + ty; }
浙公网安备 33010602011771号