利用XtraDiagram.DiagramControl进行流程图形的绘制和控制
DevExpress提供了一个比较强大的图形绘制工具,可以用于绘制各种图形,如流程图、组织机构图等等,本篇随笔介绍XtraDiagram.DiagramControl的使用,以及利用代码对其属性进行控制,以及利用图形模具的自定义操作,实现一些简单流程图形的绘制和处理。
DiagramControl是类似Visio的绘图控件,以前我2006年的就接触使用Visio的二次开发,当时开始还是利用VB6 + VIsio2003进行二次开发的,后来把它改良为C# + Visio进行二次开发,DiagramControl的对象模型很类似Visio的相关对象模型,如对于工具栏的形状,称之为模具(Stencil),Visio也是称之为Stencil, DiagramControl里面的很多接口名称依旧采用Stencil进行命名,因此估计也是借鉴了很多Visio的对象设计知识,如果您对Visio二次开发感兴趣,可以参考我的随笔文章《Visio二次开发》,里面有很多相关的内容。
而如果想了解这个控件的相关知识和使用,参考官网的案例和说明应该是比较好的教程(https://docs.devexpress.com/WindowsForms/118290/controls-and-libraries/diagrams/getting-started )。
1、DiagramControl控件的使用
DiagramControl是一个界面控件,类似Visio SDK里面的DrawingControl的存在,可以通过它进行图形的绘制,各种窗口的显示和隐藏,以及跟踪各种事件的处理。
DiagramControl控件拖动到窗体中后,会自动增加一些属性窗口,上排的绘图工具中的按钮是我添加的,用来测试该控件的一些属性的控制。
1)属性窗口的显示和隐藏(折叠)
这个通过控制diagramControl1.OptionsView.PropertiesPanelVisibility 属性就可以实现对这个属性窗口的控制了。
里面显示一些系统位置和内容信息,以及一些自定义信息的窗口,后面我会介绍如何自定义处理这些模具的属性。
通过按钮处理的代码,我们可以实现对这个窗口的显示或者隐藏处理。
//切换属性窗口的显示或关闭
var status = diagramControl1.OptionsView.PropertiesPanelVisibility;
diagramControl1.OptionsView.PropertiesPanelVisibility = (status == PropertiesPanelVisibility.Visible ? PropertiesPanelVisibility.Collapsed : PropertiesPanelVisibility.Visible);
2)模具形状窗口的显示或隐藏
模具形状的窗口,它是放在一个面板里面,我们只需要通过控制该面板的显示或者隐藏就可以了,如下代码所示。
//切换模具形状窗口的显示或关闭
var status = diagramToolboxDockPanel1.Visibility;
diagramToolboxDockPanel1.Visibility = (status == DevExpress.XtraBars.Docking.DockVisibility.Visible ? DevExpress.XtraBars.Docking.DockVisibility.Hidden : DevExpress.XtraBars.Docking.DockVisibility.Visible);
或者通过控件的Toolbar属性进行控制,一样的效果。
//切换模具形状窗口的显示或关闭
var status = this.diagramControl1.OptionsView.ToolboxVisibility;
this.diagramControl1.OptionsView.ToolboxVisibility = status == ToolboxVisibility.Closed ? ToolboxVisibility.Full : ToolboxVisibility.Closed;
3)放大缩小窗口的显示或者隐藏
同样我们也可以控制放大缩小窗口的显示或者隐藏,它也是图形绘制的一个常见的窗口。我们只需要判断或者设置diagramControl1.OptionsView.ShowPanAndZoomPanel 属性就可以了,如下代码所示。
//切换放大缩小窗口的显示或关闭
var status = diagramControl1.OptionsView.ShowPanAndZoomPanel;
diagramControl1.OptionsView.ShowPanAndZoomPanel = !status;
4)其他属性的处理
另外,我们可以通过控制一些属性,实现对标尺、网格、只读视图等模式进行控制。
//是否显示标尺
this.diagramControl1.OptionsView.ShowRulers = this.chkRuler.Checked;
//是否显示网格
this.diagramControl1.OptionsView.ShowGrid = this.chkGrid.Checked;
//是否只读视图
this.diagramControl1.OptionsProtection.IsReadOnly = this.chkReadOnly.Checked;
2、绘图的处理事件
在绘制图形的时候,一般来说我们可能需要切换点选模式或者连接线模式,因此可以通过它的属性ActiveTool进行设置。在点选模式下,可以对图形进行拖动、放大缩小、旋转等处理,连接线模式下,则会加亮连接点,便于自动绘制连接线。
private void btnPointerMode_Click(object sender, EventArgs e)
{
diagramControl1.OptionsBehavior.ActiveTool = diagramControl1.OptionsBehavior.PointerTool;
} private void btnConnectorMode_Click(object sender, EventArgs e)
{
diagramControl1.OptionsBehavior.ActiveTool = diagramControl1.OptionsBehavior.ConnectorTool;
}
当然,我们也可以通过对鼠标行为的分析来进行控制,如果鼠标悬停或者放置在图形上,就自动切换模式为连接线模式,否则为点选模式,那么只需要判断鼠标的移动行为即可自动处理,如下代码所示。
/// <summary>
/// 实现对图形自动切换到连接点模式
/// </summary>
private void diagramControl1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
return; DiagramItem item = diagramControl1.CalcHitItem(e.Location);
if (item == null)
{
diagramControl1.OptionsBehavior.ActiveTool = diagramControl1.OptionsBehavior.PointerTool;
return;
}
else if (item is DiagramConnector)
{
diagramControl1.OptionsBehavior.ActiveTool = diagramControl1.OptionsBehavior.ConnectorTool;
return;
} Rect itemBounds = new Rect(new Point(item.Position.X, item.Position.Y), new Size(item.Width, item.Height));
PointFloat documentPoint = diagramControl1.PointToDocument(new PointFloat(e.Location));
DiagramHitInfo[] hitInfo = diagramControl1.CalcHitInfo(documentPoint);
if (itemBounds.Contains(new Point(documentPoint.X, documentPoint.Y)))
{
itemBounds.Inflate(-5, -5);
if (!itemBounds.Contains(new Point(documentPoint.X, documentPoint.Y)))
{
diagramControl1.OptionsBehavior.ActiveTool = diagramControl1.OptionsBehavior.ConnectorTool;
return;
}
}
diagramControl1.OptionsBehavior.ActiveTool = diagramControl1.OptionsBehavior.PointerTool;
}
另外图形的保存xml、PNG、PDF处理和加载代码如下所示。
/// <summary>
/// 保存XML和图片文件
/// </summary>
private void SaveXml()
{
var xml = Path.Combine(Application.StartupPath, "MyFlowShapes.xml");
diagramControl1.SaveDocument(xml); var pngFile = Path.Combine(Application.StartupPath, "MyFlowShapes.png");
diagramControl1.ExportDiagram(pngFile);
}
private void btnLoadXml_Click(object sender, EventArgs e)
{
var xml = FileDialogHelper.OpenXml();
if(!string.IsNullOrEmpty(xml))
{
diagramControl1.LoadDocument(xml);
}
}
最终案例的效果如下所示。
3、注册自定义的形状
在实际的图形绘制开发中,我们可以需要创建一些指定的形状模具,那么我们弄好后一般可以存放在XML中,然后进行加载到控件上来,如下代码就是注册自定义的形状的处理。
/// <summary>
/// 注册自定义的形状。
/// 自定义图形是以XML文件形式进行保存,图形需要按照规定XML格式进行绘制
/// </summary>
private void LoadShapes2()
{
var projectName = "SmallExampleDemo.Examples.XtraDiagram";
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(projectName + ".CustomContainers.xml"))
{
var stencil = DiagramStencil.Create(MyStencilId, MyStencilName, stream, shapeName => shapeName);
DiagramToolboxRegistrator.RegisterStencil(stencil);
}
diagramControl1.SelectedStencils = new StencilCollection(MyStencilId);//(MyStencilId, BasicShapes.StencilId);
}
我们只需要设置选中的图形就可以了,其他有需要的可以从More Shapes中选择即可。
我们如果需要在属性窗口中显示自定义的属性,那么我们需要一些代码开发才能实现。
我们首先需要继承一个DiagramShape的子类,然后实现自己自定义的属性定义,如下代码所示。
对自定义属性的处理,需要在事件中实现
diagramControl1.CustomGetEditableItemProperties += DiagramControl_CustomGetEditableItemProperties;
通过对它进行判断可以实现自定义属性的显示处理
void DiagramControl_CustomGetEditableItemProperties(object sender, DiagramCustomGetEditableItemPropertiesEventArgs e)
{
if (e.Item is DiagramShapeEx)
{
e.Properties.Add(TypeDescriptor.GetProperties(typeof(DiagramShapeEx))["Status"]);
e.Properties.Add(TypeDescriptor.GetProperties(typeof(DiagramShapeEx))["TypeName"]);
}
}
然后我们可以注册创建自己的模具形状集合,如下代码所示。
/// <summary>
/// 创建自定义的模具
/// </summary>
/// <returns></returns>
DiagramStencil CreateCustomDrawShapesStencil()
{
var stencilId = "CustomedFlowShape";
var stencilName = "流程图";
var shapeSizeSmall = new Size(100, 37.5);
var shapeSize = new Size(100, 75); DiagramControl.ItemTypeRegistrator.Register(typeof(DiagramShapeEx));
var stencil = new DiagramStencil(stencilId, stencilName); //流程类型
stencil.RegisterTool(new FactoryItemTool("StartEnd", () => "流程开始", diagram => {
var shape = new DiagramShapeEx(BasicFlowchartShapes.StartEnd, "流程开始");
shape.Appearance.BackColor = Color.Red;
return shape;
}, shapeSizeSmall));
stencil.RegisterTool(new FactoryItemTool("Decision", () => "流程条件", diagram => {
var shape = new DiagramShapeEx(BasicFlowchartShapes.Decision, "流程条件");
shape.Appearance.BackColor = Color.FromArgb(199, 115, 1);//Color.Red;
return shape;
}, shapeSize));
这两个流程开始,流程条件,我们直接是从 BasicFlowchartShapes 集合中借用过来,构建自己的自定义对象的,默认创建的对象是方形的。
如果我们需要动态构建其他自定义类型,我们可以指定它的颜色等样式,从而构建不同类型的图形。
//循环添加相关流程节点
var procNames = new List<string> { "审批", "归档", "阅办", "会签", "领导批示分阅"};
//定义几个初始化颜色顺序
var colors = new List<Color> { Color.DeepSkyBlue, Color.ForestGreen, Color.Violet, Color.Yellow, Color.Blue, Color.Orange, Color.Indigo, Color.Purple, Color.Black, Color.Brown, Color.Pink };
int i = 0;
foreach (string name in procNames)
{
var shapeId = string.Format("Process_{0}", i++); stencil.RegisterTool(new FactoryItemTool(shapeId, () => name, diagram =>
{
var shape = new DiagramShapeEx(name, Status.Inactive);
var index = procNames.IndexOf(name);
var color = colors[index % 10];//Color.Red;
var fontColor = (color == Color.Yellow) ? Color.Black : Color.White; //没什么作用
//shape.ThemeStyleId = GetStyle(index); //从Accent1样式开始 DiagramShapeStyleId.Styles[index];//
shape.Appearance.BackColor = color;
shape.Appearance.BorderSize = 3;
shape.Appearance.Font = new Font("宋体", 12f, FontStyle.Bold);
shape.Appearance.ForeColor = fontColor;
return shape;
}, shapeSize));
}
这样就有不同颜色的图形对象了。
根据这些我们就可以绘制出自己的各种流程图了,并且也可以根据数据库的信息,进行动态绘制展示。
利用XtraDiagram.DiagramControl进行流程图形的绘制和控制的更多相关文章
- Quartz2D常见图形的绘制:线条、多边形、圆
UI高级 Quartz2D http://ios.itcast.cn iOS学院 掌握 drawRect:方法的使用 常见图形的绘制:线条.多边形.圆 绘图状态的设置:文字颜色.线宽等 图形上下文状 ...
- HTML5 Canvas ( 填充图形的绘制 ) closePath, fillStyle, fill
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果
利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果 前言 近日公司接到一个轨道系统的需求,需要将地铁线路及列车实时位置展示在大屏上.既然是大屏项目,那视觉效果当然是第一重点,咱们可以先来看看项 ...
- 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解
本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...
- 【HarmonyOS】【xml】使用xml绘制视频播放控制栏
本文记录HarmonyOS使用xml绘制视频播放控制栏 效果图如下 代码如下 点击查看代码 <?xml version="1.0" encoding="utf-8& ...
- 利用Microsoft VC++6.0 的MFC 的绘图工具实现简单图形的绘制
MFC运算功能强大,拥有完备的绘图功能. 在Windows平台上,应用程序的图形设备接口(graphics device interface,GDI)被抽象为设备上下文(Dev ...
- 利用CSS3 clip-path裁剪各种图形。
'clip-path'是css3的一个强大属性,我们可以利用它来绘制各种各样的图形,当然不只是这些,接下来一起看看它的强大功能吧. 首先介绍的是clip-path里面的polygon功能,我们可以通过 ...
- 利用matplotlib的plot函数实现图像绘制
模式识别的一个实验,要求画出贝叶斯决策的图.这里我是利用python中的matplotlib库实现的图线的拟合.主要对于matplotlib的使用可以参照博客:webary 如果要绘制三维图像可以参考 ...
- Qt之图形(绘制漂亮的圆弧)
简述 综合前面对二维绘图的介绍,想必我们对一些基本绘图有了深入的了解,下面我们来实现一些漂亮的图形绘制. 简述 圆形 效果 源码 弧形 效果 源码 文本 效果 源码 旋转 效果 源码 圆形 经常地,我 ...
随机推荐
- redis无损数据迁移
在dba眼中,redis仅仅是一个缓存,不适合作为存储来使用,不管是redis-sentinel集群还是cluster集群,在redis主节点发生意外宕机时没有机制来保证主从节点数据的一致性.但是,很 ...
- 阿里巴巴稀疏模型训练引擎-DeepRec
导读:DeepRec从2016年起深耕至今,支持了淘宝搜索.推荐.广告等核心业务,沉淀了大量优化的算子.图优化.Runtime优化.编译优化以及高性能分布式训练框架,在稀疏模型的训练方面有着优异性能的 ...
- python学习-Day20
目录 今日内容详细 作业讲解 re模块补充说明 findall的优先级查询 通过索引的方式单独获取分组内匹配到的数据 分组之后还可以给组起别名 split的优先级查询 collections模块 具名 ...
- vue 设置动态标题
在 router/index.js 文件中设置 meta:{title:'标题'} 和 router.beforeEach,即可实现功能, 代码如下: import { createRouter, c ...
- JDBC往数据库传值中文乱码以及时区不一致解决
设置一下时区和编码就可以了 "jdbc:mysql://localhost:3306/jdbcprac?characterEncoding=UTF-8&&useSSL=fal ...
- Kubernetes容器之间的通信浅谈
公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ 作者: Matt Zand 和 Jim Sullivan 译者: 穿过生命散发芬芳F Kubernetes是一个容器化的解决 ...
- 手脱无名壳tslgame_rl
1.使用Detect It Easy查壳,该壳未显示出壳信息,至于为何有壳,我们使用IDA打开,查看其的导入表,其中没有太多函数使用: 2.我们使用x32dbg打开,运行至入口点,此处没有pushad ...
- 有关 ThreadLocal 的一切
早上好,各位新老读者们,我是七淅(xī). 今天和大家分享的是面试常驻嘉宾:ThreadLocal 当初鹅厂一面就有问到它,问题的答案在下面正文的第 2 点. 1. 底层结构 ThreadLocal ...
- Springcloud及Git线上配置详解
SpringCloud 这个阶段该如何学? 三层架构 + MVC 框架: Spring IOC AOP SpringBoot,新一代的JavaEE开发标准,自动装配 模块化~ all in one,代 ...
- mysql allow remote host
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; FLUSH PRIVILEG ...