惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News | PayPal Newsroom
The Last Watchdog
The Last Watchdog
S
Secure Thoughts
Forbes - Security
Forbes - Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
PCI Perspectives
PCI Perspectives
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
Last Week in AI
Last Week in AI
Blog — PlanetScale
Blog — PlanetScale
Hacker News: Ask HN
Hacker News: Ask HN
H
Heimdal Security Blog
D
Docker
Cloudbric
Cloudbric
P
Privacy International News Feed
S
Security Affairs
TaoSecurity Blog
TaoSecurity Blog
博客园 - 聂微东
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Tenable Blog
Scott Helme
Scott Helme
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
P
Palo Alto Networks Blog
小众软件
小众软件
L
LINUX DO - 最新话题
美团技术团队
Google Online Security Blog
Google Online Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
The Hacker News
The Hacker News
Webroot Blog
Webroot Blog
T
Tor Project blog
G
Google Developers Blog
A
About on SuperTechFans
Y
Y Combinator Blog
K
Kaspersky official blog
A
Arctic Wolf
量子位
I
InfoQ
V
Visual Studio Blog
T
Troy Hunt's Blog
C
Cybersecurity and Infrastructure Security Agency CISA
J
Java Code Geeks
博客园 - 【当耐特】
GbyAI
GbyAI

博客园 - 云飞扬

揭开文档在线编辑和预览的神秘面纱 AI的正确使用方法 详解HFBPM开发框架(下) 详解HFBPM开发框架(中) 详解HFBPM开发框架(上) 浅谈数据访问层 流程梳理的重要性 菜鸟电子面单对接技术方案(link) 数据库升级工具 HF Code Designer 代码生成器 HF工作流引擎与现有业务系统的整合 一步一步学习开发BPM工作流系统--------(七)BPM表单设计和业务展现平台 一步一步学习开发BPM工作流系统--------(六)BPM流程设计器(2) 一步一步学习开发BPM工作流系统--------(五)用户、组织机构和权限管理 一步一步学习开发BPM工作流系统--------(四)BPM数据库访问层 一步一步学习开发BPM工作流系统--------(三)开发WinForm的应用平台-2 - 云飞扬 一步一步学习开发BPM工作流系统--------(三)开发WinForm的应用平台-1 一步一步学习开发BPM工作流系统--------(二)BPM工作流系统的组成部分 - 云飞扬 一步一步学习开发BPM工作流系统--------(一)为什么要开发工作流系统 支持多数据库本地和远程调用的数据访问层架构
一步一步学习开发BPM工作流系统--------(六)BPM流程设计器(1)
云飞扬 · 2012-08-23 · via 博客园 - 云飞扬

流程设计器是编辑流程模版的工具,可视化的流程设计器能直观的编辑流程模版,所见即所得,如下图是我们要做的流程设计器:

image

流程模版存放流程流转所需要的信息,使用流程设计器来管理流程模版是比较常见的方式,我见过一些流程系统使用表格的形式来管理,那样很不直观。也许是因为技术的原因,该篇就介绍如何制作这样的流程设计器,用到的技术GDI+绘图,数据库存取。要了解GDI+绘图技术的可以先看一下http://www.cnblogs.com/stg609/archive/2008/03/16/1108333.html 这个博客的介绍,比较基础。

在开始之前,先介绍一下目前市场上流程设计器的几种形式,无非就是两种形式一种是B/S的,一种是C/S,我个人感觉这两种形式没必要苛求那一种,各有优缺点,B/S的安装方便一些,不用安装直接使用,但操作灵活性比不上C/S的,B/S的流程设计器目前有几种技术可以实现,一种是js,一种是Silverlight或者FLex,还有一种是用ActiveX插件。流程设计器一般是管理员、实施人员使用,用户群体比较单一固定,但使用要求比较高,必须方便灵活,所以我们的流程设计器采用C/S的方式,结合我们前面提供的WCF远程数据服务,可以实现远程流程模版管理,绝对不亚于B/S的流程设计器。

该篇内容比较多,先看一下要介绍的内容:

1、流程模版分类管理

2、如何使用GDI+画流程图

3、流程任务节点类型和属性

4、流程模版的导入导出

下面详细介绍每一部分:

1、流程模版分类管理

按照业务对流程模版进行分类,建立一个树形结构的分类机制,不限级数,如下图:

image

每个分类上可以配置管理界面,如下图:可以配置两种形式的管理界面,一种是web页面,一种是winform的窗体。这些管理界面是在业务平台上使用。

image

2、如何使用GDI+画流程图

      GDI+:Graphics Device Interface Plus是2D图形处理的技术,在C#.NET中,使用GDI+处理二维(2D)的图形和图像,使用DirectX处理三维(3D)的图形图像,图形图像处理用到的主要命名空间是System . Drawing:提供了对GDI+基本图形功能的访问,主要有Graphics类、Bitmap类、从Brush类继承的类、Font类、Icon类、Image类、Pen类、Color类等。

     了解了GDI+基本概念后,再来了解2D图像处理的原理,在窗体或者控件上显示图形或者图像必须使用OnPaint事件,把成像的代码放到该事件里,在窗体重画时才会保持显示状态,如果不放在该事件里,那么在窗体重画时图像就无法显示,所以OnPaint事件是图像显示的重要事件,每个窗体和窗体上的控件都是利用该事件来显示的,做过控件开发的应该很了解这个机制。

         根据以上原理,流程图的原理也就很简单了,就是在画布上把表示各种类型的任务节点画出来,再用带箭头的连线把他们连接起来,把这个过程放到画布的OnPaint事件里面,这样流程图就可以展现出来,同时选中的节点画上选中标志。要实现可视化操作还需要解决一下问题:

   a、读取流程模版

       从数据库中把流程模版中的所有任务节点和连线读出来,放到全局的数组中,在OnPaint事件中把TaskItems 数组和LineItems数组中的图像画出来。如下图数组定义:

        /// <summary>
        /// 流程模板所有节点列表
        /// </summary>
        public ArrayList TaskItems = new ArrayList();
        /// <summary>
        /// 流程模板所有连线列表
        /// </summary>
        public ArrayList LineItems=new ArrayList();   

     由于重画事件执行频率比较高,所以该过程内的代码都是操作内存对象,读写数据库的代码不要放到这里面。

    详细代码参见HF.WorkFlow.Component项目的WorkPlace.cs

   b、如何选中任务节点和多选节点。

         选中节点的原理是通过图像坐标来判断的,每个图形或者图像都有一个Rectangle区域,该区域记录着节点x,y轴坐标和长度宽度,只要鼠标落点在这个区域内视为选中该节点。这里有个处理技巧,一般任务节点的尺寸是实际看到的图片尺寸,但是在选中的时候鼠标点中图标周围也算选中,这是一种模糊处理的概念,很好用,如果不这么处理,点选任务节点的时候会很别扭,非得点中图片内才算选中。也可以这么理解,任务节点的有效区域范围是图片本身的尺寸加上一个边框,只要在边框内都算点中。我们在OnPaint事件中把选中的节点的边框以毛边的形式显示出来,并加上8个方向的方块句柄,这样选择的节点就很形象了。如下图:

image

判断节点是否选中的函数:

        /// <summary>
        /// 判断给定坐标是否在组件的边界矩形内
        /// </summary>
        /// <param name="thePoint">给定坐标</param>
        /// <returns>是否选中</returns>
        public bool Contains(Point thePoint)
        {
            if(!Selected)//没有选中
                return bounds.Contains(thePoint);
            else
            {
                Rectangle selectionRect=bounds;//节点图像的尺寸区域
                selectionRect.Inflate(SystemInformation.FrameBorderSize);//通过各方向的给定值增加矩形的尺寸,加上选择边框
                return selectionRect.Contains(thePoint);
            }
        }

     然后把选中的节点添加到一个全局的数组中,供拖动或者删除使用。

         /// <summary>
        /// 选中的节点列表
        /// </summary>
        public SelectedItems SelectedItems = new SelectedItems();

   多选的处理原理是判断所有节点的坐标是否在鼠标经过的区域内,如果在该区域内添加到SelectedItems 数组中,画布重画的时候会自动给SelectedItems数组的节点画上选中标志,即毛边和抓取句柄。下图是鼠标圈选时滑过的矩形橡皮圈,鼠标抬起时在该区域内的节点都添加到选中数组中。

image

    c、如何移动选中的节点。

前面介绍了如何选中节点,移动节点就是改变选中节点的坐标,只要配合鼠标移动事件和鼠标抬起事件就可以。在鼠标移动时画出移动的轨迹很关键,这样更直观一些,如下图:

image

方框为移动经过时留下的轨迹,当鼠标抬起时确定选中节点的坐标。重新激活重画事件OnPaint,重画事件会重新在界面上画出任务节点和连线。这就达到了移动的目的。

   d、保存流程模版

    我们在读取模版的时候把任务节点和连线都存放到数组中,那么在保存的时候把数组中的任务节点和连线写入到数据库中即可。

上面是流程设计器的主要原理,下面来用代码实现一个简单的设计器。

a、先定义一个任务节点的基类

   首选要确定有多少种类型的节点,每种类型的节点的功能是什么,使用什么样式的图标等,后面会介绍节点类型,这里我们先定义一个节点的基类BaseComponent,所有节点类型都继承该类。

    基类的属性字段包括节点的坐标、图片、字体、名称、类型等基本属性。

    基类的方法包括画节点的方法,选中节点的方法。

    代码比较多复制到这里也不方便,具体代码参见BaseComponent.cs。

b、如何画节点的毛边和抓取句柄

    前面见过毛边是任务节点图像周围的边框,详细定义参见Bounds.cs,八个方向的抓取句柄参见GrabHandles.cs。

c、如何对齐节点

    节点的对齐操作参见Dragger.cs

d、如何定义一个多选时的橡皮圈

  定义圈选时的橡皮圈轨迹,参见Rubberband.cs。

以上代码中都有详细的注释。

下一篇我们介绍节点类型和节点属性。