using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; using System.Collections; using System.Linq; namespace HySoft.FlowEditor { public partial class FlowEditorCanvas : UserControl { #region 字段 const int KeyVal_Del = 46; const int KeyVal_Enter = 13; /// /// 节点连接线与矩形边距的宽度 /// static int _nodeMargin = 10; List _nodeList; List _lineList; FlowNode[] _selectNodes; FlowLine[] _selectLines; /// /// 选中操作的开始鼠标点 /// Point _selectBegainPos; /// /// 是否开始选中操作 /// bool _bBegainSelect; /// /// 用于显示选中框的容器 /// Panel _selectControl; /// /// 是否是多个节点移动 /// bool _bMultiNodeMove = false; #endregion #region 属性 /// /// 节点列表 /// public List NodeList { get { return _nodeList; } } /// /// 线列表 /// public List LineList { get { return _lineList; } } /// /// 被选中节点组 /// public FlowNode[] SelectedNodes { get { return _selectNodes; } set { SetSelectedNodes(value); } } /// /// 被选中连线组 /// public FlowLine[] SelectedLines { get { return _selectLines; } set { _selectLines = value; } } #endregion #region 事件 /// /// 节点单击事件 /// public Delegate_ClickNode Evt_ClickNode; /// /// 节点双击事件 /// public Delegate_DoubleClickNode Evt_DoubleClickNode; /// /// 线单击事件 /// public Delegate_ClickLine Evt_ClickLine; /// /// 线双击事件 /// public Delegate_DoubleClickLine Evt_DoubleClickLine; /// /// 回车键按下事件 /// public Delegate_KeyDown_Enter Evt_KeyDown_Enter; /// /// 删除键按下事件 /// public Delegate_KeyDown_Del Evt_KeyDown_Del; #endregion #region 公开方法 /// /// 构造方法 /// public FlowEditorCanvas() { _nodeList = new List(); _lineList = new List(); InitializeComponent(); _bBegainSelect = false; _selectControl = new Panel(); _selectControl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; _selectControl.BackColor = Color.Transparent; _selectControl.Visible = false; } /// /// 添加一个流程节点 /// /// public void AddANode(FlowNode node) { _nodeList.Add(node); AddNodeControlToCanvasControl(node.Control); SetSelectedNodes(new FlowNode[] { node }); } /// /// 添加一个流程节点 /// /// /// public void AddANode(FlowNode node, Point coord) { _nodeList.Add(node); AddNodeControlToCanvasControl(node.Control); SetSelectedNodes(new FlowNode[] { node }); } /// /// 添加一条线 /// /// 要添加的线 /// 头节点 /// 尾节点 public void AddALine(FlowLine line, FlowNode headNode, FlowNode tailNode) { AddALine(line, headNode, null, tailNode, null); } /// /// 添加一条线 /// /// 要添加的线 /// 头节点 /// 头结点的出口,如果为null,方法会自动创建一个出口 /// 尾节点 /// 尾结点的入口,如果为null,方法会自动创建一个入口 public void AddALine(FlowLine line, FlowNode headNode, NodePort headNodeOutputPort, FlowNode tailNode, NodePort tailNodeInputPort) { List points = GetLinePointListWidthScroll(headNode, tailNode); line.PointList = points; NodePort outputPort = headNodeOutputPort; if (outputPort == null) { outputPort = new NodePort(); tailNode.AddOutputPort(outputPort); } tailNode.AddLineToOutPort(line, outputPort); NodePort inputPort = tailNodeInputPort; if (inputPort == null) { inputPort = new NodePort(); headNode.AddInputPort(inputPort); } headNode.AddLineToInputPort(line, inputPort); _lineList.Add(line); AddLineControlToCanvasControl(line.Control); } /// /// 删除一个流程节点 /// 同时会删除与该流程节点连接的线及其线对应的两端节点的端口 /// /// public void DelNode(FlowNode node) { if (_nodeList.IndexOf(node) < 0) return; SetSelectedNodes(null); NodePort[] inputPorts = node.InputPortList.ToArray(); if (inputPorts != null && inputPorts.Length > 0) { foreach (NodePort nodePort in inputPorts) DelLine(nodePort.Line, true, true); } NodePort[] outputPorts = node.OutputPortList.ToArray(); if (outputPorts != null && outputPorts.Length > 0) { foreach (NodePort nodePort in outputPorts) DelLine(nodePort.Line, true, true); } RemoveNodeControlFromCanvasControl(node.Control); _nodeList.Remove(node); } /// /// 删除一条线 /// /// 指定的线 /// 是否同时移除线对应的出口 /// 是否同时移除线对应的入口 /// 移除成功 public void DelLine(FlowLine line, bool bRemoveHeadNodeOutputPort, bool bRemoveTailNodeInputPort) { if (line == null) return; if (line.TailNode != null && line.TailNodePort != null) { NodePort inputPort = line.TailNode.FindInputPort(line); if (inputPort != null) { line.TailNode.RemoveLineFromInputPort(line, inputPort); if (bRemoveTailNodeInputPort) line.TailNode.RemoveInputPort(inputPort); } } if (line.HeadNode != null && line.HeadNodePort != null) { NodePort outputPort = line.HeadNode.FindOutputPort(line); if (outputPort != null) { line.HeadNode.RemoveLineFromOutputPort(line, outputPort); if (bRemoveTailNodeInputPort) line.HeadNode.RemoveOutputPort(outputPort); } } RemoveLineControlFromCanvasControl(line.Control); _lineList.Remove(line); } /// /// 设置被选中的节点 /// /// public void SetSelectedNodes(FlowNode[] nodes) { //保存老的选中节点 FlowNode[] oldSelectedNodes = _selectNodes; //将新的被选中节点设置为未被选中状态 _selectNodes = nodes; if (_selectNodes != null) { foreach (FlowNode node in nodes) { if (!node.Control.BeSelected) { node.Control.BeSelected = true; Trace.WriteLine(node.Name + "被设置为选中"); } } } //将原来的被选中节点设置为未被选中状态 if (oldSelectedNodes != null) { if (_selectNodes == null) { foreach (FlowNode node in oldSelectedNodes) { node.Control.BeSelected = false; Trace.WriteLine(node.Name + "被设置为未选中"); } } else { foreach (FlowNode node in oldSelectedNodes) { //为了防止闪烁,只将在老的选中节点中而不在新的选中节点中的节点设置成不被选中 if (!(_selectNodes != null && _selectNodes.Contains(node))) { node.Control.BeSelected = false; Trace.WriteLine(node.Name + "被设置为未选中"); } } } } } /// /// 设置被选中的线 /// /// public void SetSelectedLines(FlowLine[] lines) { //保存老的选中线 FlowLine[] oldSelectedLines = _selectLines; //将新的被选中线设置为未被选中状态 _selectLines = lines; if (_selectLines != null) { foreach (FlowLine line in lines) { if (!line.Control.BeSelected) { line.Control.BeSelected = true; Trace.WriteLine(line.Name + "被设置为选中"); } } } //将原来的被选中线设置为未被选中状态 if (oldSelectedLines != null) { //如果新选中的线为空,则将全部的老选中线设置为未被选中 if (_selectLines == null) { foreach (FlowLine line in oldSelectedLines) { line.Control.BeSelected = false; Trace.WriteLine(line.Name + "被设置为未选中"); } } else {//否则设置原来选中的线设置为未被选中状态 foreach (FlowLine line in oldSelectedLines) { //为了防止闪烁,只将在老的选中线中而不在新的选中线中的线设置成不被选中 if (!(_selectLines !=null && _selectLines.Contains(line))) { line.Control.BeSelected = false; Trace.WriteLine(line.Name + "被设置为未选中"); } } } } } #endregion #region 控件响应方法 private void nodeControl_MouseDown(object sender, MouseEventArgs e) { FlowNodeControl nodeControl = (FlowNodeControl)sender; //判断是否是单个节点移动 if (_selectNodes != null && _selectNodes.Length >= 2 && _selectNodes.Contains(nodeControl.FlowNode)) _bMultiNodeMove = true; if (!_bMultiNodeMove) {//单节点移动 nodeControl.BeMoveing = true; nodeControl.MovePos = new Point(e.X, e.Y); SetSelectedNodes(new FlowNode[] { nodeControl.FlowNode }); } else {//多节点移动 foreach (FlowNode node in _selectNodes) { FlowNodeControl control = node.Control; control.BeMoveing = true; control.MovePos = new Point(e.X, e.Y); } } } private void nodeControl_MouseMove(object sender, MouseEventArgs e) { FlowNodeControl nodeControl = (FlowNodeControl)sender; if (nodeControl.BeMoveing) { //判断是否是单个节点移动 if (!_bMultiNodeMove) {//单节点移动 nodeControl.Left += Convert.ToInt16(e.X - nodeControl.MovePos.X);//设置x坐标. nodeControl.Top += Convert.ToInt16(e.Y - nodeControl.MovePos.Y);//设置y坐标. ResetNodeLines(nodeControl.FlowNode); } else {//多节点移动 if (_selectNodes != null) { foreach (FlowNode node in _selectNodes) { FlowNodeControl control = node.Control; control.Left += Convert.ToInt16(e.X - control.MovePos.X);//设置x坐标. control.Top += Convert.ToInt16(e.Y - control.MovePos.Y);//设置y坐标. ResetNodeLines(control.FlowNode); } } } } } private void nodeControl_MouseUp(object sender, MouseEventArgs e) { FlowNodeControl nodeControl = (FlowNodeControl)sender; if (nodeControl.BeMoveing) { //判断是否是单个节点移动 if (!_bMultiNodeMove) {//单节点移动 nodeControl.BeMoveing = false; nodeControl.Left += Convert.ToInt16(e.X - nodeControl.MovePos.X);//设置x坐标. nodeControl.Top += Convert.ToInt16(e.Y - nodeControl.MovePos.Y);//设置y坐标. ResetNodeLines(nodeControl.FlowNode); } else {//多节点移动 if (_selectNodes != null) { foreach (FlowNode node in _selectNodes) { FlowNodeControl control = node.Control; control.BeMoveing = false; control.Left += Convert.ToInt16(e.X - nodeControl.MovePos.X);//设置x坐标. control.Top += Convert.ToInt16(e.Y - nodeControl.MovePos.Y);//设置y坐标. ResetNodeLines(control.FlowNode); } } _bMultiNodeMove = false; } } } private void nodeControl_Click(object sender, EventArgs e) { if (!_bMultiNodeMove) {//如果不是多节点移动,则触发节点单击事件 FlowNode node = ((FlowNodeControl)sender).FlowNode; SetSelectedNodes(new FlowNode[] { node }); SetSelectedLines(null); if (Evt_ClickNode != null) Evt_ClickNode(node); } } private void nodeControl_DoubleClick(object sender, EventArgs e) { FlowNode node = ((FlowNodeControl)sender).FlowNode; SetSelectedNodes(new FlowNode[] { node }); SetSelectedLines(null); SetSelectedNodes(new FlowNode[] { node }); if (Evt_DoubleClickNode != null) Evt_DoubleClickNode(node); } private void nodeControl_KeyDown(object sender, KeyEventArgs e) { PressKeyDown(e.KeyValue); } private void lineControl_Click(object sender, EventArgs e) { FlowLine line = ((FlowBrokenLineControl)sender).FlowLine; SetSelectedNodes(null); SetSelectedLines(new FlowLine[] { line }); if (Evt_ClickLine != null) Evt_ClickLine(line); } private void lineControl_DoubleClick(object sender, EventArgs e) { Trace.WriteLine("-----------lineControl_DoubleClick"); FlowLine line = ((FlowBrokenLineControl)sender).FlowLine; SetSelectedNodes(null); SetSelectedLines(new FlowLine[] { line }); if (Evt_DoubleClickLine != null) Evt_DoubleClickLine(line); } private void lineControl_KeyDown(object sender, KeyEventArgs e) { PressKeyDown(e.KeyValue); } private void FlowEditorCanvas_MouseDown(object sender, MouseEventArgs e) { Trace.WriteLine("---------Canvas_MouseDown"); //if (e.Button == System.Windows.Forms.MouseButtons.Left) //{ // _bBegainSelect = true; // _selectBegainPos = e.Location; // _selectControl.Location = e.Location; // this.Controls.Add(_selectControl); //} } private void FlowEditorCanvas_MouseMove(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left && !_bBegainSelect) { _bBegainSelect = true; _selectBegainPos = e.Location; _selectControl.Location = e.Location; this.Controls.Add(_selectControl); } if (_bBegainSelect) { Trace.WriteLine("---------Canvas_MouseMove"); if (!_selectControl.Visible) _selectControl.Visible = true; //计算当前点相对于起始点的位置,假设起始点在坐标原点 //俄制象限 int offsetX = e.X - _selectBegainPos.X; int offsetY = e.Y - _selectBegainPos.Y; _selectControl.Height = Math.Abs(offsetY); _selectControl.Width = Math.Abs(offsetX); if(offsetX >= 0) { if(offsetY >= 0) {//第四象限 } else {//第一象限 _selectControl.Location = new Point(_selectBegainPos.X, e.Y); } } else { if(offsetY >= 0) {//第三象限 _selectControl.Location = new Point(e.X, _selectBegainPos.Y); } else {//第二象限 _selectControl.Location = new Point(e.X, e.Y); } } SetSelectedNodes(GetSelectedNode()); SetSelectedLines(null); } } private void FlowEditorCanvas_MouseUp(object sender, MouseEventArgs e) { Trace.WriteLine("---------Canvas_MouseUp"); if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (_selectControl.Visible) _selectControl.Visible = false; _bBegainSelect = false; this.Controls.Remove(_selectControl); } } private void FlowEditorCanvas_Click(object sender, EventArgs e) { if (!_bBegainSelect) { Trace.WriteLine("---------Canvas_Click"); SetSelectedNodes(null); SetSelectedLines(null); } } private void FlowEditorCanvas_DoubleClick(object sender, EventArgs e) { SetSelectedNodes(null); SetSelectedLines(null); } private void FlowEditorCanvas_KeyDown(object sender, KeyEventArgs e) { PressKeyDown(e.KeyValue); } #endregion #region 私有方法 /// /// 获取两个节点之间最短路径的折线的点 /// /// 第一个节点 /// 第二个节点 /// static List GetTwoNodeShortestPathLinePointList(FlowNode node1, FlowNode node2) { //获取两个节点的连接点 List points = new List(); int X = node2.CenterPoint.X - node1.CenterPoint.X; int Y = node2.CenterPoint.Y - node1.CenterPoint.Y; if (X >= 0) { if (Math.Abs(Y) <= Math.Abs(X)) { Point point_1 = new Point(node1.RightPoint.X, node1.RightPoint.Y); points.Add(point_1); if (Y != 0) { Point point_2 = new Point(node1.RightPoint.X + _nodeMargin, point_1.Y); points.Add(point_2); Point point_3 = new Point(point_2.X, node2.LeftPoint.Y); points.Add(point_3); } Point point_4 = new Point(node2.LeftPoint.X, node2.LeftPoint.Y); points.Add(point_4); return points; } } if (X < 0) { if (Math.Abs(Y) <= Math.Abs(X)) { Point point_1 = new Point(node1.LeftPoint.X, node1.LeftPoint.Y); points.Add(point_1); if (Y != 0) { Point point_2 = new Point(node1.LeftPoint.X - _nodeMargin, node1.LeftPoint.Y); points.Add(point_2); Point point_3 = new Point(point_2.X, node2.LeftPoint.Y); points.Add(point_3); } Point point_4 = new Point(node2.RightPoint.X, node2.RightPoint.Y); points.Add(point_4); return points; } } if (Y >= 0) { if (Math.Abs(Y) >= Math.Abs(X)) { Point point_1 = new Point(node1.BottomPoint.X, node1.BottomPoint.Y); points.Add(point_1); if (X != 0) { Point point_2 = new Point(node1.BottomPoint.X, point_1.Y + _nodeMargin); points.Add(point_2); Point point_3 = new Point(node2.TopPoint.X, point_2.Y); points.Add(point_3); } Point point_4 = new Point(node2.TopPoint.X, node2.TopPoint.Y); points.Add(point_4); return points; } } if (Y < 0) { if (Math.Abs(Y) >= Math.Abs(X)) { Point point_1 = new Point(node1.TopPoint.X, node1.TopPoint.Y); points.Add(point_1); if (X != 0) { Point point_2 = new Point(node1.TopPoint.X, node1.TopPoint.Y - _nodeMargin); points.Add(point_2); Point point_3 = new Point(node2.BottomPoint.X, point_2.Y); points.Add(point_3); } Point point_4 = new Point(node2.BottomPoint.X, node2.BottomPoint.Y); points.Add(point_4); return points; } } return points; } //2017-5-16画直线 static List GetTwoNodeShortestPathLinePointListNEW(FlowNode node1, FlowNode node2) { //获取两个节点的连接点 List points = new List(); int X = node2.CenterPoint.X - node1.CenterPoint.X; int Y = node2.CenterPoint.Y - node1.CenterPoint.Y; if (X >= 0) { if (Math.Abs(Y) <= Math.Abs(X)) { Point point_1 = new Point(node1.RightPoint.X, node1.RightPoint.Y); points.Add(point_1); Point point_2 = new Point(node2.LeftPoint.X , node2.LeftPoint.Y); points.Add(point_2); /*if (Y != 0) { Point point_2 = new Point(node1.RightPoint.X + _nodeMargin, point_1.Y); points.Add(point_2); Point point_3 = new Point(point_2.X, node2.LeftPoint.Y); points.Add(point_3); }*/ //Point point_4 = new Point(node2.LeftPoint.X, node2.LeftPoint.Y); //points.Add(point_4); return points; } else if (Math.Abs(Y) > Math.Abs(X)) { Point point_1 = new Point(node1.BottomPoint.X, node1.BottomPoint.Y); points.Add(point_1); Point point_2 = new Point(node2.TopPoint.X + node2.TopPoint .Y); points.Add(point_2); return points; } } if (X < 0) { if (Math.Abs(Y) <= Math.Abs(X)) { Point point_1 = new Point(node1.LeftPoint.X, node1.LeftPoint.Y); points.Add(point_1); if (Y != 0) { Point point_2 = new Point(node1.LeftPoint.X - _nodeMargin, node1.LeftPoint.Y); points.Add(point_2); Point point_3 = new Point(point_2.X, node2.LeftPoint.Y); points.Add(point_3); } Point point_4 = new Point(node2.RightPoint.X, node2.RightPoint.Y); points.Add(point_4); return points; } } if (Y >= 0) { if (Math.Abs(Y) >= Math.Abs(X)) { Point point_1 = new Point(node1.BottomPoint.X, node1.BottomPoint.Y); points.Add(point_1); if (X != 0) { Point point_2 = new Point(node1.BottomPoint.X, point_1.Y + _nodeMargin); points.Add(point_2); Point point_3 = new Point(node2.TopPoint.X, point_2.Y); points.Add(point_3); } Point point_4 = new Point(node2.TopPoint.X, node2.TopPoint.Y); points.Add(point_4); return points; } } if (Y < 0) { if (Math.Abs(Y) >= Math.Abs(X)) { Point point_1 = new Point(node1.TopPoint.X, node1.TopPoint.Y); points.Add(point_1); if (X != 0) { Point point_2 = new Point(node1.TopPoint.X, node1.TopPoint.Y - _nodeMargin); points.Add(point_2); Point point_3 = new Point(node2.BottomPoint.X, point_2.Y); points.Add(point_3); } Point point_4 = new Point(node2.BottomPoint.X, node2.BottomPoint.Y); points.Add(point_4); return points; } } return points; } /// /// 获取基于滚动条的连线的点列表 /// /// /// /// List GetLinePointListWidthScroll(FlowNode node1, FlowNode node2) { List points = FlowEditorCanvas.GetTwoNodeShortestPathLinePointList(node1, node2); if (points != null) { for (int i = 0; i < points.Count; i++) { points[i] = new Point(points[i].X - this.AutoScrollPosition.X, points[i].Y - this.AutoScrollPosition.Y); } } return points; } /// /// 重新布局指定线的连接点 /// /// void ResetLine(FlowLine line) { Trace.WriteLine("ResetLine Begain----------------------"); List points = GetLinePointListWidthScroll(line.HeadNode, line.TailNode); line.PointList = points; Trace.WriteLine("HeadNode=" + line.HeadNode.CenterPoint.ToString()); Trace.WriteLine("HeadNodeTopPoint=" + line.HeadNode.TopPoint.ToString()); Trace.WriteLine("TailNode=" + line.TailNode.CenterPoint.ToString()); Trace.WriteLine("TailNodeBottomPoint=" + line.HeadNode.BottomPoint.ToString()); foreach (Point point in points) Trace.WriteLine(point); Trace.WriteLine("ResetLine End--------------------"); } /// /// 重新布局和指定节点相连的线 /// /// void ResetNodeLines(FlowNode node) { List inputPortList = node.InputPortList; if (inputPortList != null && inputPortList.Count > 0) { foreach (NodePort port in inputPortList) { ResetLine(port.Line); } } List outputPortList = node.OutputPortList; if (outputPortList != null && outputPortList.Count > 0) { foreach (NodePort port in outputPortList) { ResetLine(port.Line); } } } /// /// 将节点控件添加到画板控件上 /// /// void AddNodeControlToCanvasControl(FlowNodeControl nodeControl) { this.Controls.Add(nodeControl); nodeControl.MouseDown += new MouseEventHandler(nodeControl_MouseDown); nodeControl.MouseUp += new MouseEventHandler(nodeControl_MouseUp); nodeControl.MouseMove += new MouseEventHandler(nodeControl_MouseMove); nodeControl.Click += new EventHandler(nodeControl_Click); nodeControl.DoubleClick += new EventHandler(nodeControl_DoubleClick); nodeControl.KeyDown += new KeyEventHandler(nodeControl_KeyDown); } /// /// 将节点控件从画板控件上移除 /// /// void RemoveNodeControlFromCanvasControl(FlowNodeControl nodeControl) { this.Controls.Remove(nodeControl); nodeControl.MouseDown -= new MouseEventHandler(nodeControl_MouseDown); nodeControl.MouseUp -= new MouseEventHandler(nodeControl_MouseUp); nodeControl.MouseMove -= new MouseEventHandler(nodeControl_MouseMove); nodeControl.Click -= new EventHandler(nodeControl_Click); nodeControl.DoubleClick -= new EventHandler(nodeControl_DoubleClick); nodeControl.KeyDown -= new KeyEventHandler(nodeControl_KeyDown); } /// /// 将线控件添加到画布控件中 /// /// void AddLineControlToCanvasControl(FlowBrokenLineControl lineControl) { lineControl.Size = new Size(1000, 1000); this.Controls.Add(lineControl); lineControl.Click += new EventHandler(lineControl_Click); lineControl.DoubleClick += new EventHandler(lineControl_DoubleClick); lineControl.KeyDown += new KeyEventHandler(lineControl_KeyDown); } /// /// 将线控件从画布控件中移除 /// /// void RemoveLineControlFromCanvasControl(FlowBrokenLineControl lineControl) { lineControl.Size = new Size(1000, 1000); this.Controls.Remove(lineControl); lineControl.Click -= new EventHandler(lineControl_Click); lineControl.DoubleClick -= new EventHandler(lineControl_DoubleClick); lineControl.KeyDown -= new KeyEventHandler(lineControl_KeyDown); } /// /// 获取选中的节点 /// /// FlowNode[] GetSelectedNode() { if (!_bBegainSelect) return null; List selectedNodeList = new List(); Rectangle selectRect = new Rectangle(_selectControl.Location, _selectControl.Size); foreach (FlowNode node in _nodeList) { Rectangle nodeRect = new Rectangle(node.Control.Location, node.Control.Size); if (selectRect.IntersectsWith(nodeRect)) selectedNodeList.Add(node); } return selectedNodeList.ToArray(); } /// /// 处理键盘按下事件 /// /// void PressKeyDown(int keyVal) { if (keyVal == KeyVal_Del) { if(Evt_KeyDown_Del != null) Evt_KeyDown_Del(); } else if (keyVal == KeyVal_Enter) { if (Evt_KeyDown_Enter != null) Evt_KeyDown_Enter(); } } #endregion } #region 画布委托定义 /// /// 鼠标单击节点 /// /// public delegate void Delegate_ClickNode(FlowNode node); /// /// 鼠标双击节点 /// /// public delegate void Delegate_DoubleClickNode(FlowNode node); /// /// 鼠标单击线 /// /// public delegate void Delegate_ClickLine(FlowLine line); /// /// 鼠标双击线 /// /// public delegate void Delegate_DoubleClickLine(FlowLine line); /// /// 删除键被按下 /// public delegate void Delegate_KeyDown_Del(); /// /// 回车键被按下 /// public delegate void Delegate_KeyDown_Enter(); #endregion }