📄 designerselector.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace WorkflowDesigner.Designer
{
/// <summary>
/// “指针”设计工具
/// </summary>
public class DesignerSelector:DesignerTool
{
#region 字段
/// <summary>
/// 开始鼠标位置的x轴坐标
/// </summary>
private int startMouseX;
/// <summary>
/// 开始鼠标位置的y轴坐标
/// </summary>
private int startMouseY;
/// <summary>
/// 记录前一个鼠标位置的x轴坐标
/// </summary>
private int prevMouseX;
/// <summary>
/// 记录前一个鼠标位置的y轴坐标
/// </summary>
private int prevMouseY;
/// <summary>
/// 选择状态
/// </summary>
private SelectState _state;
#endregion
#region 属性
/// <summary>
/// 开始鼠标位置的x轴坐标
/// </summary>
public int StartMouseX
{
get { return startMouseX; }
set { startMouseX = value; }
}
/// <summary>
/// 开始鼠标位置的y轴坐标
/// </summary>
public int StartMouseY
{
get { return startMouseY; }
set { startMouseY = value; }
}
/// <summary>
/// 记录前一个鼠标位置的x轴坐标
/// </summary>
public int PrevMouseX
{
get { return prevMouseX; }
set { prevMouseX = value; }
}
/// <summary>
/// 记录前一个鼠标位置的y轴坐标
/// </summary>
public int PrevMouseY
{
get { return prevMouseY; }
set { prevMouseY = value; }
}
#endregion
#region 构造函数
/// <summary>
/// 构造函数
/// </summary>
public DesignerSelector()
{
_state = SelectState.None;
}
#endregion
#region 操作
#region 私有
/// <summary>
/// 保存前一个鼠标所在的位置
/// </summary>
/// <param name="x">前一个鼠标所在位置的x轴坐标</param>
/// <param name="y">前一个鼠标所在位置的y轴坐标</param>
private void SavePrevMousePosition(int x, int y)
{
prevMouseX = x;
prevMouseY = y;
}
#endregion
#region 保护
#endregion
#region 公用
/// <summary>
/// 当鼠标按下时
/// </summary>
/// <param name="x">鼠标点所在的位置x轴坐标</param>
/// <param name="y">鼠标点所在的位置y轴坐标</param>
public override void OnMouseDown(int x, int y)
{
//使画布被鼠标捕获
this.Ctrl.SetCapture();
//得到鼠标点击下去的对象(调用document中的方法)
HitTestResult result = this.Ctrl.Document.HitTest(x,y);
//如果为空
if (result == null)
{
//取消所有被选择的可视化对象
this.Ctrl.Document.ResetSelected();
//重新绘制
this.Ctrl.RedrawAll();
//设置状态为框选
this._state = SelectState.RangeSelect;
}
//如果存在被点到的对象
else if (result.state == HitTestState.Center)
{
//如果该对象没被选中
if (result.result.IsSelected == false)
{
//如果“指针”当前不在选择状态
if (_state != SelectState.Select)
{
//清空所有的选择项
Ctrl.Document.ResetSelected();
}
//如果没有按下control键
else if (!IsControlPressed())
{
//清空所有的选择项
Ctrl.Document.ResetSelected();
}
//设置点到$的可视化对象为被选中
result.result.IsSelected = true;
Ctrl.RedrawAll();
}
//设置“指针”状态为选择状态
this._state = SelectState.Select;
}
else
{
//设置“指针”状态为选择状态
this._state = SelectState.Resize;
}
//将前一个鼠标位置设置为鼠标当前位置
SavePrevMousePosition(x, y);
//鼠标开始位置x轴坐标设置为鼠标当前的x轴坐标
startMouseX = x;
//鼠标开始位置y轴坐标设置为鼠标当前的y轴坐标
startMouseY = y;
}
/// <summary>
/// 当鼠标弹开时
/// </summary>
/// <param name="x">鼠标点所在的位置x轴坐标</param>
/// <param name="y">鼠标点所在的位置y轴坐标</param>
public override void OnMouseMove(int x, int y)
{
//如果当前指针状态为选中状态
if (this._state == SelectState.Select)
{
//如果前一个鼠标所在的位置不是目前所在的位置
if ((this.prevMouseX != x) || (this.prevMouseY != y))
{
//设置指针状态为拖拽状态
this._state = SelectState.Drag;
//保存前一个节点的位置
SavePrevMousePosition(x, y);
}
}
//如果状态为拖
else if (this._state == SelectState.Drag)
{
this.Ctrl.Document.MoveSelected(x - prevMouseX, y - prevMouseY);
//重画
Ctrl.RedrawAll();
//保存前一个节点的位置
SavePrevMousePosition(x, y);
}
//如果状态为框选
else if (this._state == SelectState.RangeSelect)
{
//得到横向滚动条和竖向滚动条交叉的(top,hight)点
Point scrollOffset = Ctrl.ScrollOffset;
//得到开始点的屏幕坐标 计算公式:[注:25为设计器画布初始时增加的偏移数值]x坐标=开始点的x轴坐标-横向滚动条+25
Point startPoint = Ctrl.PointToScreen(new Point(startMouseX - scrollOffset.X + 25, startMouseY - scrollOffset.Y + 25));
//这里需要增加画橡皮筋××××××××××根据点画矩形
//根据开始点和width height得到框 宽度=前一个鼠标x轴-开始点的鼠标x轴〔注:这里的x轴坐标不是屏幕坐标〕
//高度=前一个鼠标y轴-开始点的鼠标y轴〔注:这里的y轴坐标不是屏幕坐标〕由于x,y是属于在第四象限里边做操作所以要用后一个点减去前一个点
//根据屏幕上的指定边界绘制框架(前一个鼠标所在位置)
ControlPaint.DrawReversibleFrame(
new Rectangle(
startPoint.X,
startPoint.Y,
prevMouseX - startMouseX,
prevMouseY - startMouseY),
Color.Black, FrameStyle.Dashed);
//根据屏幕上的指定边界绘制框架(当前鼠标所在位置)
ControlPaint.DrawReversibleFrame(
new Rectangle(
startPoint.X,
startPoint.Y,
x - startMouseX,
y - startMouseY),
Color.Black, FrameStyle.Dashed);
//保存前一个节点的位置
SavePrevMousePosition(x, y);
}
}
/// <summary>
/// 当鼠标移动时
/// </summary>
/// <param name="x">鼠标点所在的位置x轴坐标</param>
/// <param name="y">鼠标点所在的位置y轴坐标</param>
public override void OnMouseUp(int x, int y)
{
//如果状态为框选
if (this._state == SelectState.RangeSelect)
{
//得到横向滚动条和竖向滚动条交叉的(top,hight)点
Point scrollOffset = Ctrl.ScrollOffset;
//得到开始点的屏幕坐标 计算公式:[注:25为设计器画布初始时增加的偏移数值]x坐标=开始点的x轴坐标-横向滚动条+25
Point startPoint = Ctrl.PointToScreen(new Point(startMouseX - scrollOffset.X + 25, startMouseY - scrollOffset.Y + 25));
//这里需要增加画橡皮筋××××××××××根据点画矩形
//根据开始点和width height得到框 宽度=前一个鼠标x轴-开始点的鼠标x轴〔注:这里的x轴坐标不是屏幕坐标〕
//高度=前一个鼠标y轴-开始点的鼠标y轴〔注:这里的y轴坐标不是屏幕坐标〕由于x,y是属于在第四象限里边做操作所以要用后一个点减去前一个点
//根据屏幕上的指定边界绘制框架(前一个鼠标所在位置)
ControlPaint.DrawReversibleFrame(
new Rectangle(
startPoint.X,
startPoint.Y,
prevMouseX - startMouseX,
prevMouseY - startMouseY),
Color.Black, FrameStyle.Dashed);
//得到最后的选择框的橡皮筋 根据当前鼠标所在位置指定边界绘制矩形
Rectangle selectedRect = new Rectangle(startMouseX, startMouseY, x - startMouseX, y - startMouseY);
//如果宽度为负数取宽度绝对值
if (selectedRect.Width < 0)
{
selectedRect.X = x;
selectedRect.Width = -selectedRect.Width;
}
//如果高度为负数取高度绝对值
if (selectedRect.Height < 0)
{
selectedRect.Y = y;
selectedRect.Height = -selectedRect.Height;
}
//框选
Ctrl.Document.RangeSelect(selectedRect);
//重画
Ctrl.RedrawAll();
}
//如果状态为拖拽
else if (this._state == SelectState.Drag)
{
//对齐掉表格
this.Ctrl.Document.AlignToGrid();
//重新绘制
this.Ctrl.RedrawAll();
}
}
/// <summary>
/// 当取消控件被鼠标捕获时
/// </summary>
public override void OnCancelCapture()
{
//释放所有被鼠标捕获的可视化对象
this.Ctrl.ReleaseCapture();
}
#endregion
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -