上一篇:使用silverlight构建一个工作流设计器(十八)-持久化数据到数据库—服务器段功能实现

19.1 规则和活动交点的平滑移动

在之前的版本中,规则和活动的关联,如果活动图形是矩形或者菱形,那么系统只定义了4个关联点,分别在上下左右,如下图所示:

附件: workflowdesigner_21.jpg

这样的关联设定也可以用,但还不是很完美,经过改进,现在实现为两个活动的中间连线与活动的相交点。如果拖动活动或者规则,那么这个交点就会平滑的移动,不会像之前那样在4个点之间跳动了,如下图所示:

附件: workflowdesigner_22.jpg

这个功能的实现不复杂,主要是分析好各种关系就可以了。下面以矩形图活动为例,具体描述一下相应的思路和代码。如下图所示:


附件: workflowdesigner_23.jpg

现在已知起始点坐标与终点坐表,以及活动A的长和宽,求从起始点到终点的连线和活动A的交点。这是一个很简单的平面几何算数题,我们需要注意的是当起始点坐标和终点坐表的相对位置不同时(例如,起始点在终点的左上、左下、右上、右下),计算公式稍有变化。下面的代码具体描述了计算方法。
  1. //起始点坐标和终点坐标之间的夹角(相对于Y轴坐标系)

  2. double angle = Math.Abs(Math.Atan((endPoint.X - beginPoint.X) / (endPoint.Y - beginPoint.Y)) * 180.0 / Math.PI);

  3. //活动的长和宽之间的夹角(相对于Y轴坐标系)

  4. double angel2 =Math.Abs( Math.Atan(PictureWidth / PictureHeight) * 180.0 / Math.PI);

  5. //半径

  6. double radio = PictureHeight<PictureWidth?PictureHeight/2:PictureWidth/2;

  7. if (angle <= angel2)//起始点坐标在终点坐标的上方,或者下方

  8. {

  9.     if (endPoint.Y < beginPoint.Y)//在上方

  10.     {

  11.         if (endPoint.X < beginPoint.X)

  12.             p.X = endPoint.X + Math.Tan(Math.PI * angle / 180.0) * radio;

  13.         else

  14.             p.X = endPoint.X - Math.Tan(Math.PI * angle / 180.0) * radio;


  15.         p.Y = endPoint.Y + PictureHeight / 2;

  16.     }

  17.     else//在下方

  18.     {

  19.         if (endPoint.X < beginPoint.X)

  20.             p.X = endPoint.X + Math.Tan(Math.PI * angle / 180.0) * radio;

  21.         else

  22.             p.X = endPoint.X - Math.Tan(Math.PI * angle / 180.0) * radio;


  23.         p.Y = endPoint.Y - PictureHeight / 2;

  24.     }

  25. }


  26. else//左方或者右方

  27. {

  28.     if (endPoint.X < beginPoint.X)//在右方

  29.     {

  30.         p.X = endPoint.X + PictureWidth / 2;

  31.         if (endPoint.Y < beginPoint.Y)

  32.             p.Y = endPoint.Y + Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;

  33.         else

  34.             p.Y = endPoint.Y - Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;

  35.     }

  36.     else//在左方

  37.     {

  38.         p.X = endPoint.X - PictureWidth / 2;

  39.         if (endPoint.Y < beginPoint.Y)

  40.             p.Y = endPoint.Y + Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;

  41.         else

  42.             p.Y = endPoint.Y - Math.Tan(Math.PI * (90 - angle) / 180.0) * radio;


  43.     }
复制代码
19.2 双击面板生成活动

这个功能也是网友的建议,现在生成活动可以使用两种方式,点击添加活动 按钮,以及使用右键菜单。根据网友建议,增加一个新的方式,双击容器面板,在当前位置生成活动。这个功能比较简单,主要是检测鼠标双击事件,然后在当前鼠标位置生成一个活动,具体的代码如下:
  1. Activity a = new Activity((IContainer)this, ActivityType.INTERACTION);

  2. a.ActivityName = Text.NewActivity + NextNewActivityIndex.ToString();

  3. Point p = e.GetPosition(this); 

  4. a.CenterPoint = new Point(p.X - this.Left, p.Y - this.Top);

  5. this.AddActivity(a);
复制代码
(文/chegan

下一篇:使用silverlight构建一个工作流设计器(二十)-增加标签(上)

源码下载
TOP