5.7 开发工作流图形定义工具
5.7.6 图形工具主界面程序
图形工具的主界面程序Form1.cs主要负责业务流程的绘制、节点等图形属性的编辑、业务流程的保存等,其主要操作函数包括:图形元素选择按钮点击事件处理方法toolBar1_ButtonClick,点击不同的图形元素按钮,可以在绘图区绘制不同的流程元素;绘图面板中鼠标点击事件处理方法Panel_MouseDown,包括对左键点击和右键点击的处理,分别对应节点等图形绘制、图形元素属性的编辑等;Panel_MouseMove绘图面板中鼠标移动事件处理方法,负责处理图形元素的移动和重新绘制;菜单点击事件处理方法,包括删除节点menuItem1_Click、编辑节点menuItem2_Click、保存流程及节点menuItem5_Click等;检查节点数组的正确性的CheckProcessModel方法、检查是否存在过程逻辑嵌套的AndNestedCheck方法等。
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
namespace drawtaskbytoolbar
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.ToolBar toolBar1;
private System.Windows.Forms.ToolBarButton toolBarButton1;
......
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.ContextMenu editMenu;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;
......
private System.ComponentModel.IContainer components;
//记录节点类型(用于点击ToolBar按钮选择节点类型)
private nodetypedefine nodetype=nodetypedefine.notask;
//左键选中的节点(用于图形拖动)
private NodeClass pickednode=null;
//右键选中的节点(用于删除节或编辑节点属性)
private NodeClass R_pickednode=null;
//节点对象集合
private NodeRecords nodearray=new NodeRecords();
//迁移对象集合
TransitionRecords transitionarray=new TransitionRecords();
//记录节点拖放的新位置
private float dragtoX;
private float dragtoY;
//鼠标点击次数,画流程迁移使用
private int clickcount=0;
//迁移的连接节点
private NodeClass node1;
private NodeClass node2;
//绘图工具
private Graphics g=null;
//构造函数
public Form1()
{
// Windows 窗体设计器支持所必需的
InitializeComponent();
}
// 应用程序的主入口点
[STAThread]
static void Main()
{
//Application.EnableVisualStyles();
Application.Run(new Form1());
}
//绘图工具条按钮点击方法(记录选择绘制的图形元素类型)
private void toolBar1_ButtonClick(object sender,
System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
//按照顺序判断点击了工具条的那个按钮
switch(toolBar1.Buttons.IndexOf(e.Button))
{
case 0:
nodetype=nodetypedefine.start;
break;
case 1:
nodetype=nodetypedefine.end;
break;
case 2:
nodetype=nodetypedefine.tasknode;
break;
case 3:
nodetype=nodetypedefine.andsplit;
break;
case 4:
nodetype=nodetypedefine.orsplit;
break;
case 5:
nodetype=nodetypedefine.andjoin;
break;
case 6:
nodetype=nodetypedefine.orjoin;
break;
case 7:
nodetype=nodetypedefine.transition;
break;
}
}
//绘图面板中鼠标被按下的事件处理
private void Panel_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
//左键按下
if(e.Button == MouseButtons.Left)
{
//如果选择了节点或迁移
if(nodetype != nodetypedefine.notask)
g=panel1.CreateGraphics();//创建Graphics对象
//如果是开始或结束节点
if(nodetype==nodetypedefine.start || nodetype==nodetypedefine.end)
{
//不能重复添加开始和结束节点
if(nodearray.HasNode(nodetype))
return;
//绘制节点框
g.DrawRectangle(new Pen(new SolidBrush(Color.LightPink),3),e.X,e.Y,60,26);
//填充节点框
g.FillRectangle(new SolidBrush(Color.FromArgb(128,255,255))
,e.X,e.Y,60,26);
//绘制节点名称
Font drawFont = new Font("宋体", 9);
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
RectangleF stringrect=new RectangleF(e.X+7,e.Y+6,46,14);
//设置开始或结束节点的显示文字
string nodename="";
if(nodetype==nodetypedefine.start)
nodename="Start";
else
nodename="End";
//绘制文字
g.DrawString(nodename,drawFont,new SolidBrush(Color.Red),stringrect
,drawFormat);
//把节点添加到节点记录集
NodeClass nodeRecord=new NodeClass(e.X,e.Y);
nodeRecord.NodeType=nodetype;
nodeRecord.NodeName=nodename;
nodeRecord.Width=60;
nodeRecord.Height=26;
nodearray.nodeList.Add(nodeRecord);
//重新设置节点类型为空
nodetype=nodetypedefine.notask;
//释放Graphics对象
g.Dispose();
}
//如果是任务节点
if(nodetype==nodetypedefine.tasknode)
{
//绘制节点框
Color rectColor=Color.LightPink;
g.DrawRectangle(new Pen(new SolidBrush(rectColor),3),e.X,e.Y,100,30);
g.FillRectangle(new SolidBrush(Color.FromArgb(0,128,255)),e.X,e.Y,100,30);
//绘制节点名称
Font drawFont = new Font("宋体", 9);
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
RectangleF stringrect=new RectangleF(e.X+5,e.Y+7,90,16);
//获取新增节点的默认名称
string nodename=nodearray.GetNewNodeName();
g.DrawString(nodename,drawFont,new SolidBrush(Color.White),stringrect
,drawFormat);
//把节点添加到节点记录集
NodeClass nodeRecord=new NodeClass(e.X,e.Y);
nodeRecord.NodeType=nodetypedefine.tasknode;
nodeRecord.NodeName=nodename;
nodeRecord.Width=100;
nodeRecord.Height=30;
nodearray.nodeList.Add(nodeRecord);
g.Dispose();
//重新设置节点类型为空
nodetype=nodetypedefine.notask;
}
//如果是过程逻辑节点
if(nodetype==nodetypedefine.andsplit || nodetype==nodetypedefine.orsplit ||
nodetype==nodetypedefine.andjoin || nodetype==nodetypedefine.orjoin)
{
//绘制节点框
g.DrawRectangle(new Pen(new SolidBrush(Color.LightPink),3),
e.X,e.Y,30,20);
g.FillRectangle(new SolidBrush(Color.FromArgb(128,255,255)),
e.X,e.Y,30,20);
//绘制节点名称
Font drawFont = new Font("宋体", 9);
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
RectangleF stringrect=new RectangleF(e.X-15,e.Y+3,60,14);
//获取新增节点的默认名称
string nodename=nodearray.GetNewLogicNodeName(nodetype);
//把节点添加到节点记录集
NodeClass nodeRecord=new NodeClass(e.X,e.Y);
nodeRecord.NodeType=nodetype;
nodeRecord.NodeName=nodename;
nodeRecord.Width=30;
nodeRecord.Height=20;
nodearray.nodeList.Add(nodeRecord);
//绘制节点名称
if(nodetype == nodetypedefine.andsplit)
nodename="And Split";
if(nodetype == nodetypedefine.andjoin)
nodename="And Join";
if(nodetype == nodetypedefine.orsplit)
nodename="Or Split";
if(nodetype == nodetypedefine.orjoin)
nodename="Or Join";
g.DrawString(nodename,drawFont,new SolidBrush(Color.Red),stringrect,
drawFormat);
//重新设置节点类型为空
nodetype=nodetypedefine.notask;
g.Dispose();
}
......(待续)