2026/4/6 12:18:25
网站建设
项目流程
StateBaseStateBase 详解 - 状态基类这是状态机系统的核心抽象基类为所有交互状态绘制状态、编辑状态、选择状态等提供了统一的框架。它管理视图引用、鼠标事件处理、光标样式、状态绘制等通用功能。 文件头部和引用// 版权信息同前// Copyright (c) HeBianGu Authors. All Rights Reserved.// ...省略usingH.Extensions.Mvvm.ViewModels.Base;// MVVM基础类DisplayBindableBaseusingSystem.Windows.Input;// 鼠标输入namespaceH.LabelImg.ShapeBox.State.Base;// 命名空间存放状态机相关的基础类️ StateBase 抽象类// 抽象基类所有交互状态的基础// 继承自 DisplayBindableBase支持MVVM属性通知// 实现 IViewState 接口定义状态的生命周期和事件publicabstractclassStateBase:DisplayBindableBase,IViewState{// 核心属性 // 当前状态关联的视图对象// 状态可以通过视图访问控件、形状集合等publicIViewView{get;set;}// 修饰键要求Ctrl、Alt、Shift等// 只有按下指定修饰键时状态才会响应鼠标事件// 默认不需要任何修饰键publicModifierKeysModifierKeys{get;set;}ModifierKeys.None;️ 鼠标事件处理方法// 鼠标事件虚方法子类可重写 // 鼠标离开控件时触发publicvirtualvoidMouseLeave(objectsender,MouseEventArgse){// 默认空实现子类可重写// 例如清除临时绘制、恢复光标等}// 鼠标释放时触发publicvirtualvoidMouseUp(objectsender,MouseButtonEventArgse){// 默认空实现子类可重写// 例如完成形状绘制、结束拖拽等}// 鼠标移动时触发publicvirtualvoidMouseMove(objectsender,MouseEventArgse){// 默认空实现子类可重写// 例如更新预览形状、移动选中对象等}// 鼠标按下时触发publicvirtualvoidMouseDown(objectsender,MouseButtonEventArgse){// 默认空实现子类可重写// 例如开始绘制形状、开始拖拽等} 辅助方法// 辅助方法 // 清除临时状态受保护子类可调用protectedvirtualvoidClear(){// 默认空实现子类可重写// 例如清除临时变量、重置标志等}// 获取状态形状视图用于绘制状态预览protectedvirtualIStateShapeViewGetStateShapeView()this.ViewasIStateShapeView;// 获取普通形状视图用于重绘形状protectedvirtualIShapeViewGetShapeView()this.ViewasIShapeView;// 刷新形状视图重绘所有形状protectedvoidRefreshShapeView(paramsIShape[]shapes){this.GetShapeView()?.DrawShapes();}// 获取元素视图用于设置光标protectedFrameworkElementGetElementView()this.ViewasFrameworkElement;// 设置鼠标光标样式protectedvoidSetCursor(Cursorcursor){varelementthis.GetElementView();if(elementnull)return;element.Cursorcursor;}// 绘制状态形状用于临时预览protectedvoidDrawStateShape(paramsIShape[]shapes){this.GetStateShapeView()?.DrawStateShape(shapes);} 生命周期方法// 状态生命周期 // 进入状态时调用publicvirtualvoidEnter(){// 默认空实现子类可重写// 例如初始化变量、设置默认光标等}// 退出状态时调用publicvirtualvoidExit(){this.Clear();// 清理临时状态this.DrawStateShape();// 清除状态预览this.Viewnull;// 释放视图引用}// 视图缩放改变时调用publicvirtualvoidScaleChanged(){// 默认空实现子类可重写// 例如重新计算坐标、更新预览等}} 状态类层次结构IViewState接口 ↓ StateBase抽象基类← 当前类 ↓ 具体状态类 ├── DrawRectState绘制矩形状态 ├── DrawCircleState绘制圆形状态 ├── SelectState选择状态 ├── MoveState移动状态 ├── ResizeState缩放状态 └── ... 更多 具体状态实现示例示例1绘制矩形状态publicclassDrawRectState:StateBase{privatePoint_startPoint;privateRectShape_previewRect;publicDrawRectState(){this.ModifierKeysModifierKeys.None;// 不需要修饰键}publicoverridevoidEnter(){// 进入状态设置十字光标this.SetCursor(Cursors.Cross);}publicoverridevoidMouseDown(objectsender,MouseButtonEventArgse){if(e.ChangedButtonMouseButton.Left){// 记录起始点_startPointe.GetPosition(this.GetElementView());// 创建预览矩形_previewRectnewRectShape();}}publicoverridevoidMouseMove(objectsender,MouseEventArgse){if(_startPoint!nulle.LeftButtonMouseButtonState.Pressed){// 获取当前点Pointcurrente.GetPosition(this.GetElementView());// 更新预览矩形RectrectnewRect(_startPoint,current);_previewRect.Rectrect;// 绘制状态形状预览this.DrawStateShape(_previewRect);}}publicoverridevoidMouseUp(objectsender,MouseButtonEventArgse){if(e.ChangedButtonMouseButton.Left_previewRect!null){// 将预览矩形添加到视图varshapeViewthis.GetShapeView();if(shapeView!null){shapeView.Shapes.Add(_previewRect);}// 清除预览this.DrawStateShape();_previewRectnull;_startPointdefault;}}publicoverridevoidExit(){// 退出时清理base.Exit();this.SetCursor(Cursors.Arrow);}}示例2选择状态publicclassSelectState:StateBase{privateIShape_selectedShape;privatePoint_dragStart;publicSelectState(){this.ModifierKeysModifierKeys.None;}publicoverridevoidEnter(){this.SetCursor(Cursors.Arrow);}publicoverridevoidMouseDown(objectsender,MouseButtonEventArgse){if(e.ChangedButtonMouseButton.Left){Pointpointe.GetPosition(this.GetElementView());varshapeViewthis.GetShapeView();// 查找被点击的形状foreach(varshapeinshapeView.Shapes){if(shapeisIHitableShapehitablehitable.Hit(null,point)){_selectedShapeshape;_dragStartpoint;// 选中形状if(shapeViewisISelectShapeBoxselectBox){selectBox.SelectShapes(shapeasISelectableShape);}break;}}}}publicoverridevoidMouseMove(objectsender,MouseEventArgse){if(_selectedShape!nulle.LeftButtonMouseButtonState.Pressed){Pointcurrente.GetPosition(this.GetElementView());Vectoroffsetcurrent-_dragStart;// 移动选中的形状if(_selectedShapeisRectShaperect){rect.RectnewRect(rect.Rect.Xoffset.X,rect.Rect.Yoffset.Y,rect.Rect.Width,rect.Rect.Height);}_dragStartcurrent;// 刷新视图this.RefreshShapeView();}}publicoverridevoidMouseUp(objectsender,MouseButtonEventArgse){_selectedShapenull;}}示例3缩放状态需要修饰键publicclassZoomState:StateBase{privatePoint_zoomCenter;privatedouble_startScale;publicZoomState(){// 需要按下 Ctrl 键才能激活this.ModifierKeysModifierKeys.Control;}publicoverridevoidMouseDown(objectsender,MouseButtonEventArgse){if(e.ChangedButtonMouseButton.Left){_zoomCentere.GetPosition(this.GetElementView());varviewthis.ViewasStateShapeBox;if(view!null){_startScaleview.Scale;}}}publicoverridevoidMouseMove(objectsender,MouseEventArgse){if(_startScale!0e.LeftButtonMouseButtonState.Pressed){Pointcurrente.GetPosition(this.GetElementView());doubledelta(current.Y-_zoomCenter.Y)/100;doublenewScale_startScale*(1delta);// 限制缩放范围newScaleMath.Max(0.1,Math.Min(10,newScale));varviewthis.ViewasStateShapeBox;if(view!null){view.ScalenewScale;}}}publicoverridevoidMouseUp(objectsender,MouseButtonEventArgse){_startScale0;}} 在 StateShapeBox 中的使用publicclassStateShapeBox:SelectShapeBox,IStateShapeView{privateIViewState_currentState;publicIViewStateViewState{get_currentState;set{// 退出当前状态_currentState?.Exit();// 进入新状态_currentStatevalue;_currentState?.Enter();}}protectedoverridevoidOnMouseDown(MouseButtonEventArgse){// 检查当前状态的修饰键要求if(_currentState?.ModifierKeysKeyboard.Modifiers){_currentState.MouseDown(this,e);if(e.Handled)return;}base.OnMouseDown(e);}protectedoverridevoidOnMouseMove(MouseEventArgse){if(_currentState?.ModifierKeysKeyboard.Modifiers){_currentState.MouseMove(this,e);if(e.Handled)return;}base.OnMouseMove(e);}protectedoverridevoidOnMouseUp(MouseButtonEventArgse){if(_currentState?.ModifierKeysKeyboard.Modifiers){_currentState.MouseUp(this,e);if(e.Handled)return;}base.OnMouseUp(e);}}设计模式分析1. 状态模式核心设计不同状态封装不同的行为。2. 模板方法模式基类定义状态的生命周期Enter、Exit和事件处理框架。3. 策略模式不同的状态实现不同的交互策略。4. 观察者模式状态监听鼠标事件并做出响应。总结成员类型用途View属性关联的视图对象ModifierKeys属性激活状态的修饰键要求MouseDown/Up/Move/Leave虚方法鼠标事件处理Enter/Exit虚方法状态生命周期SetCursor()方法设置鼠标光标DrawStateShape()方法绘制临时预览RefreshShapeView()方法刷新形状视图核心价值统一框架所有状态使用相同的接口和生命周期修饰键支持可以指定 Ctrl/Alt/Shift 激活状态视图解耦通过 IView 接口访问控件功能临时绘制支持状态预览如绘制中的形状光标管理统一的光标设置方法这个基类是状态机系统的基石为所有交互状态提供了强大而灵活的基础设施