•    前言

  今天,要跟大家一起分享是“GDI+动态生成流程图”的功能。别看名字高大上(也就那样儿--!),其实就是动态生成控件,然后GDI+绘制直线连接控件罢了。实际项目效果图如下:

  • Talk is Cheap,Show me the Code

首先,人靠衣装马靠鞍!在绘制流程图之前,我们得有个高大上的背景来衬托,比如网格背景:

代码如下:

  /// <summary>
/// 初始化网格
/// </summary>
private void InitGridLine()
{
pictureBox1.BorderStyle = BorderStyle.Fixed3D;
pictureBox1.Focus();
m_picture = pictureBox1.CreateGraphics();
Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics gp = Graphics.FromImage(canvas);
DrawGrid(gp);
pictureBox1.BackgroundImage = canvas;
pictureBox1.Refresh();
}
//绘制网格
private void DrawGrid(Graphics gp)
{
for (int i = 0; i < Row; i++)
{
gp.DrawLine(new Pen(Color.LightCyan), (i + 1) * pictureBox1.Width / Row, 0, (i + 1) * pictureBox1.Width / Row, pictureBox1.Height);
}
for (int i = 0; i < colums; i++)
{
gp.DrawLine(new Pen(Color.LightCyan), 0, (i + 1) * pictureBox1.Height / colums, pictureBox1.Width, (i + 1) * pictureBox1.Height / colums);
}
}

     我们此处以PictureBox为画布,初始化好网格背景后,就可以开始创建流程标签了,效果如下:

代码如下:

/// <summary>
/// 绘制元素,此处以Label为例
/// </summary>
/// <returns></returns>
private Label createBlock(string lblName)
{
try
{
Label label = new Label();
label.AutoSize = false;
//TODO:如需动态生成每个标签元素位置,请根据实际情况,初始化标签的Location即可。此处默认X=150,Y 以75间隔递增
label.Location = new Point(150, iPosition);
iPosition = iPosition + 75;
label.Size = new Size(89, 36);
label.BackColor = Color.DarkOliveGreen;
label.ForeColor = Color.Black;
label.FlatStyle = FlatStyle.Flat;
label.TextAlign = ContentAlignment.MiddleCenter;
label.Text = lblName;
//TODO;可以绑定标签元素的右键事件
//label.ContextMenuStrip = contextBlock;
pictureBox1.Controls.Add(label);
//拖拽移动
MoveBlock(label);
return label;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return null;
}

    实现动态生成的标签拖拽移动效果,方法如下:

 //标签移动效果
private void MoveBlock(Label block, Label endBlock = null)
{
block.MouseDown += (ss, ee) =>
{
if (ee.Button == System.Windows.Forms.MouseButtons.Left)
fPoint = Control.MousePosition;
};
block.MouseMove += (ss, ee) =>
{
if (ee.Button == System.Windows.Forms.MouseButtons.Left)
{
Point temp = Control.MousePosition;
Point res = new Point(fPoint.X - temp.X, fPoint.Y - temp.Y); block.Location = new Point(block.Location.X - res.X,
block.Location.Y - res.Y);
fPoint = temp;
pictureBox1.Invalidate(); // <------- draw the new lines
}
};
}

      生成好背景网格和标签,以及实现标签的拖拽后,就需要绘制直线按自己需求,实现连接了。本文我们用 Tuple 来实现两个标签的连接关系。

//用于存储需要直线连接的元素
List<Tuple<Label, Label>> lines = new List<Tuple<Label, Label>>();

    绑定PictureBox的Paint事件,利用GDI+的DrawLine实现绘制直线。

private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
foreach (Tuple<Label, Label> t in lines)
{
Point p1 = new Point(t.Item1.Left + t.Item1.Width / 2,
t.Item1.Top + t.Item1.Height / 2);
Point p2 = new Point(t.Item2.Left + t.Item2.Width / 2,
t.Item2.Top + t.Item2.Height / 2); e.Graphics.DrawLine(Pens.Black, p1, p2);
}
}

      好了,所有工作都已完成,此时,只需要把想要连接的两个标签添加到当前集合中,即可完成直线的连接功能。效果如图

  参考文献:

     https://docs.microsoft.com/zh-cn/dotnet/api/system.tuple-2?view=netcore-3.1

  https://stackoverflow.com/questions/31626027/how-to-connect-with-line-shapes-labels-on-runtime/31642448#31642448?newreg=de162494b077460383555e4da76bdd18

  

  • 结束语

   由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号回复:erp,即可获取Fucking ERP所有源码示例~!有疑问的也可以CALL我一起探讨。

最后,感谢您的耐心陪伴!如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!

最新文章

  1. css3实现轮播
  2. iOS9的一些问题
  3. FooTable高级的响应式表格jQuery插件
  4. Saltstack系列3:Saltstack常用模块及API
  5. this.Invoke和this.BeginInvoke的区别
  6. 教程-Delphi设置功能表
  7. django + nginx + raspberypi + pidaro
  8. 基于meanshift的手势跟踪与电脑鼠标控制(手势交互系统)
  9. Java进阶(四十三)线程与进程的区别
  10. C# - 设计模式 - 策略模式
  11. Java的运算符
  12. wc语法2
  13. vue(ajax:axios中文文档)
  14. JavaScript -- Window-Move,Print
  15. 【WIN10】Segoe MDL2 Assets
  16. 2016中国app年度排行榜:十大行业、25个领域、Top 500 和2017趋势预测
  17. [label][翻译][JavaScript]如何使用JavaScript操纵radio和check boxes
  18. 转载------让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
  19. 我是IT小小鸟(读后感)
  20. DPDK报文分类与访问控制

热门文章

  1. java基础(swing+jsp+mybatis配置)
  2. 6 年前,只会 JSP 和 Servlet 就可以找到工作
  3. OpenvSwitch系列之七 meter表限速
  4. 剑指 Offer 56 - II. 数组中数字出现的次数 II
  5. 用Java爬虫爬取凤凰财经提供的沪深A股所有股票代号名称
  6. [Java数据结构]Map的contiansKey和List的contains比较
  7. Solr专题(一)手把手教你搭建Solr服务
  8. Linux设备驱动模型简述(源码剖析)
  9. 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)
  10. zepto | 用事件委托去解决无法给新增添的DOM添加事件的问题