winform快速开发平台 -> 工作流组件(仿GooFlow)

对于web方向的工作流,一直在用gooflow对于目前我的winform开发平台却没有较好的工作流组件。

   针对目前的项目经验告诉我们。一个工作流控件是很必要的。 当然在winform方面的工作流第三方组件在网上找了很久,也没有发现自己比较心仪的组件。

对于工作流组件通过web方式来实现具有绝对的优势。我的这套winform平台当然也不能少了工作流组件。

通过winform来实现自己的工作流组件,目前我想到的指能通过GDI+重绘的方式来实现工作流的方案。

  说干就干,如下图这是我通过GDI+绘制的工作流控件:

设计思想:

控件中我们需要一些定义的节点:如开始、结束、自定义节点、画线,和一个内容画布组成

通过抽象出线、点、以及item。进行重绘。

画布进行双缓冲来解决绘制时导致的出线闪屏问题。

简单介绍:

画布中的网格绘制方法:

 var gridPen = new Pen(Color.Silver)
{
    DashStyle = DashStyle.Custom,
    DashPattern = new float[] { 2f, 2f }
};
 for (int column = 0; column < (int)Math.Ceiling((double)this.Width / (double)gridAverage); column++)
{
    bufferGraphics.DrawLine(gridPen, new Point(column * gridAverage, 0), new Point(column * gridAverage, this.Height));
}
 for (int row = 0; row < (int)Math.Ceiling((double)this.Height / (double)gridAverage); row++)
{
    bufferGraphics.DrawLine(gridPen, new Point(0, row * gridAverage), new Point(this.Width, row * gridAverage));
}

  绘制节点抽象类型代码:

public enum ItemType
{
    /// <summary>
    /// 开始
    /// </summary>
    Start,
    /// <summary>
    /// 工作流
    /// </summary>
    Custom,
    /// <summary>
    /// 线
    /// </summary>
    Line,
    /// <summary>
    /// 结束
    /// </summary>
    End
 }

绘制连线

public void DrawLine(Graphics grp, Pen pen)
{
    if (m_startPoint == null || m_endPoint == null) return;

    var startX = m_startPoint.ItemLocate.X + m_startPoint.ItemImage.Width / 2;
    var startY = m_startPoint.ItemLocate.Y + m_startPoint.ItemImage.Height / 2;

    var endX = m_endPoint.ItemLocate.X + m_endPoint.ItemImage.Width / 2;
    var endY = m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height / 2;

    #region 计算开始点位置
    if (m_startPoint.ItemLocate.X < m_endPoint.ItemLocate.X)
    {
        if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y - m_startPoint.ItemLocate.Y)
        {
            startX = m_startPoint.ItemLocate.X + m_startPoint.ItemImage.Width / 2;
            startY = m_startPoint.ItemLocate.Y + m_startPoint.ItemImage.Height;
        }
        else if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height)
        {
            startX = m_startPoint.ItemLocate.X + m_startPoint.ItemImage.Width;
            startY = m_startPoint.ItemLocate.Y + m_startPoint.ItemImage.Height / 2;
        }
        else
        {
            startX = m_startPoint.ItemLocate.X + m_startPoint.ItemImage.Width / 2;
            startY = m_startPoint.ItemLocate.Y;
        }
    }
    else
    {
        if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y - m_startPoint.ItemLocate.Y)
        {
            startX = m_startPoint.ItemLocate.X + m_startPoint.ItemImage.Width / 2;
            startY = m_startPoint.ItemLocate.Y + m_startPoint.ItemImage.Height;
        }
        else if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height)
        {
            startX = m_startPoint.ItemLocate.X;
            startY = m_startPoint.ItemLocate.Y + m_startPoint.ItemImage.Height / 2;
        }
        else
        {
            startX = m_startPoint.ItemLocate.X + m_startPoint.ItemImage.Width / 2;
            startY = m_startPoint.ItemLocate.Y;
        }
    }
    #endregion

    #region 计算结束点位置

    if (m_startPoint.ItemLocate.X < m_endPoint.ItemLocate.X)
    {
        if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y - m_startPoint.ItemLocate.Y)
        {
            endX = m_endPoint.ItemLocate.X + m_endPoint.ItemImage.Width / 2;
            endY = m_endPoint.ItemLocate.Y;
        }
        else if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height)
        {
            endX = m_endPoint.ItemLocate.X;
            endY = m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height / 2;
        }
        else
        {
            endX = m_endPoint.ItemLocate.X + m_endPoint.ItemImage.Width / 2;
            endY = m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height;
        }
    }
    else
    {
        if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y - m_startPoint.ItemLocate.Y)
        {
            endX = m_endPoint.ItemLocate.X + m_endPoint.ItemImage.Width / 2;
            endY = m_endPoint.ItemLocate.Y;
        }
        else if (m_startPoint.ItemLocate.Y < m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height)
        {
            endX = m_endPoint.ItemLocate.X + m_endPoint.ItemImage.Width;
            endY = m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height / 2;
        }
        else
        {
            endX = m_endPoint.ItemLocate.X + m_endPoint.ItemImage.Width / 2;
            endY = m_endPoint.ItemLocate.Y + m_endPoint.ItemImage.Height;
        }
    }
    #endregion
    var startPoint = new Point(startX, startY);
    var endPoint = new Point(endX, endY);

    grp.DrawLine(pen, startPoint, endPoint);
}

  

通过一点一滴的付出,每个时间点都会看到他的完善。同时也期待着的他的成长。

时间: 2024-12-05 02:03:48

winform快速开发平台 -> 工作流组件(仿GooFlow)的相关文章

winform快速开发平台 -&gt; 基础组件之分页控件

一个项目控件主要由及部分的常用组件,当然本次介绍的是通用分页控件. 处理思想:我们在处理分页过程中主要是针对数据库操作. 一般情况主要是传递一些开始位置,当前页数,和数据总页数以及相关关联的业务逻辑. 当然我们不可能将控件的所有事件都发布出来. 我们返现所有的按钮操作都是围绕着我们的的查询记录来进行操作. 至此我们只需要提供出一个事件方法. 对外开放进行数据绑定即可. 完成对数据的分页参数处理. 分页控件如下图所示: 相关业务代码:主要代码由事件委托来处理 有了通用的分页控件,我们发现并没有绑定

winform快速开发平台-&gt;让有限的资源创造无限的价值!

最近一直在维护一套自己的快速开发平台. 主要应对针对C/S架构下的项目.然而对winform这快,还真没有看到过相对好的快速开发平台, 何为快速,在博客园逛了了好久, 预览了很多通用权限管理系统. 确实通过通用权限管理系统我们能快速的解决针对winform项目中的权限管理模块,节省这部分时间来更好的完善项目的的实际业务模块. 真的很不错. 有吉日嘎拉.湖南胡勇等等吧.忽然发现这些只是满足了我们的唯一的权限模块.当我们接到一个时间紧迫的项目我们是否能只通过这套权限管理来解决项目问题呢,显然是不能的

SNF开发平台WinForm之十三-时间轴控件使用-SNF快速开发平台3.3-Spring.Net.Framework

一.显示效果如下: 二.在控件库里选择UCTimeAxis 拖拽到窗体里. 三.加入以下代码,在load事件里进行调用就可以运行了. #region 给时间轴控件加载数据 private void UCTimeAxisData() { //增加节点 List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); list.Add(new KeyValueP

SNF开发平台WinForm之九-代码生成器使用说明-SNF快速开发平台3.3-Spring.Net.Framework

下面就具体的使用说明: 1.获取代码生成器的授权码(根据本机)-----还原数据库-------改config-----代码生成器 改代码生成器Config 2.登录代码生成器 3.查看是否连接成功 4.配置参数 下图,可在字段右键选择控件编码字段,控件名称字段 5.生成代码 6.启动程序 这个系列教程文档,欢迎转载: SNF开发平台WinForm之十-Excel导入http://www.cnblogs.com/spring_wang/p/6128604.html SNF开发平台WinForm之

SNF开发平台WinForm之八-自动升级程序部署使用说明-SNF快速开发平台3.3-Spring.Net.Framework

9.1运行效果: 9.2开发实现: 1.首先配置服务器端,把“SNFAutoUpdate2.0\服务器端部署“目录按网站程序进行发布到IIS服务器上. 2.粘贴语句,生成程序 需要调用的应用程序的Load事件或者Program入口的Main方法第一行代码加上如下代码: 注意:是主程序的 Load事件要加上调整自动更新程序的代码.要以模式打开窗口.如果没有差异会自动关闭升级窗口显示主窗口. 3.把下面目录里的文件拷贝到 应用程序的同级目录下: 4.配置WINFORMS应用程序目录下Updateli

SNF开发平台WinForm之十-Excel导入-SNF快速开发平台3.3-Spring.Net.Framework

7.1运行效果: 2.Excel导入开发实现 2.1. 创建窗体,修改命名空间 新增的窗体命名“FrmImport表名”,这个导入窗口比较其它窗口会特殊一些,需要继承BaseFormImport父级窗体 2.2.在新建窗体中写方法 构造方法,是用来设置 导入的窗体名称,和下载导入模版名称,指定必填列. 2.3.AddItem在“导入数据”事件时会被调用,并且每一行数据转换成实体对象过来,我们可以对实体对象进行操作保存或者其它处理. 2.4.添加导入按钮 2.5.在调用按钮事件写入调用导入窗体代码

Winform开发框架之通用高级查询模块--SNF快速开发平台3.3-Spring.Net.Framework

最近项目确实忙,但也是一直忙于有关项目和框架技术的事情,也一直致力于改善我的WInform开发框架.使得自己及客户使用起来更加方便,更加友好,更加高效. 在很多程序模块中都很常见,也是给客户扩展查询的一个很好的补充,由于我一直希望我的Winform开发框架能够精益求精,所以做了这个模块,希望对今后我自己所有的项目以及框架本身,都能高效的使用. 1.通用高级查询模块的用途及介绍 既然称之为通用查询模块,那么他就不能与具体的表字段有耦合关系,但是要实现具体的查询,必须通过某种方式进行属性传递,实现更

如何利用快速开发平台可视化开发工作流

我们先来看看什么是工作流? 所谓工作流引擎是指workflow作为应用系统的一部分,并为之提供对各应用系统有决定作用的根据角色.分工和条件的不同决定信息传递路由.内容等级等核心解决方案.工作流引擎包括流程的节点管理.流向管理.流程样例管理等重要功能. 就好比一辆汽车,外表做得再漂亮,如果发动机有问题就只是一个摆设.应用系统的弹性就好比引擎转速方面的性能,加速到100 公里需要1 个小时(业务流程发生变动需要进行半年的程序修改)还能叫好车吗?引擎动不动就熄火(程序因为逻辑的问题陷入死循环)的车还敢

开发指南专题十:JEECG微云快速开发平台--表单校验组件ValidForm

10.4Validform对象[方法支持链式调用] 如示例 var demo=$(".formsub").Validform(),那么demo对象会有以下属性和方法可以调用: tipmsg[object] 如:demo.tipmsg.s="error! no messageinputed."; 通过该对象可以修改除 tit 以外的其他提示文字,这样可以实现同一个页面的不同表单使用不同的提示文字. 具体可修改的提示文字 $.Tipmsg={//默认提示文字; tit: