前言

首先,跟守护在作者公众号和私信作者催更的朋友们道个歉。疫情的原因,公司从年初到现在一直处于996+的高压模式,导致公众号更新频率较低。而且作者每更新一篇原创公众号,既要对自己沉淀知识负责,也要对愿意和作者一起探讨一起学习一起进步的小伙伴儿们负责,防止误人子弟。所以作者的每一篇原创,都是作者在有限时间内仔细推敲后的产物,希望大家可以理解。

Talk is Cheap! 

前面分享的几个章节,差不多把实际用到的控件和容器的封装、扩展、重绘都举例到了(后续如果还有其他特例,作者也会更新进来)。今天要分享的依然是“Fucking ERP”系列中比较重要的环节——流程图。

本章的流程图并非工作流,winform在市面上有很多经典的工作流组件比如微软的WWF,还有很多开源自主研发的工作流组件等等,后续作者实际用到的话也会分享出来和大家一起探讨。此处分享的流程图,主要是"标识"的作用,主要用来表示业务数据的流转,具体数据如何流转,都需要各位后台自行处理(说白了,就是从A表查出数据,插入到B表,然后更新A表标识罢了。)

Show me the Code!

首先,界面加载的时候,初始化控件可用性,以及所有模块列表

private void frmWorkFlow_Load(object sender, EventArgs e)
{
//创建大模块
CreateModule();
this.TabPage1.PageVisible = false;
this.TabPage2.PageVisible = false;
this.TabPage3.PageVisible = false; this.kzxsBtnAddButton.Enabled = false;
this.kzxsBtnAddLabel.Enabled = false;
this.kzxsBtnAddLine.Enabled = false; this.Btn_SaveButton.Enabled = false;
this.Btn_SaveLabel.Enabled = false;
this.Btn_SaveLine.Enabled = false;

为了满足演示效果,本位都用DataTable来模拟数据库操作。初始化模块菜单方法如下:

 //创建主目录
public void CreateModule()
{
//此处拿DataTable来存储数据库的所有菜单节点,此处用销售模块来举例
DataTable dtSalesOrder = new DataTable();
dtSalesOrder.Columns.Add("sID", typeof(Guid));
dtSalesOrder.Columns.Add("sModel", typeof(string));
dtSalesOrder.Columns.Add("iOrder", typeof(int));
dtSalesOrder.Rows.Add(new object[] { Guid.NewGuid(), "销售模块", }); DataRow[] dr = dtSalesOrder.Select("", "iOrder"); //存在子菜单生产树结构
if (dr.Length > )
{
foreach (DataRow row in dr)
{
DevExpress.XtraEditors.SimpleButton sb = new DevExpress.XtraEditors.SimpleButton();
sb.Name = row["sID"].ToString();
sb.Text = row["sModel"].ToString();
sb.Tag = row["sModel"].ToString();
sb.TabIndex = int.Parse(row["iOrder"].ToString());
sb.Dock = DockStyle.Top;
sb.Height = ;
sb.Click += onBtnClick;
panelControl1.Controls.Add(sb); }
}
}

模块按钮绑定了点击事件,用于触发当前选择的菜单的流程图(代码逻辑已经添加,时间有限,本文不做处理,如有疑问,可公众号私信作者一起探讨)

private void onBtnClick(object sender, EventArgs e)
{
sModel = ((DevExpress.XtraEditors.SimpleButton)sender).Name.ToString().Trim();
sModelName = ((DevExpress.XtraEditors.SimpleButton)sender).Text.ToString().Trim();
//根据选择的菜单模块,加载当前菜单的流程图
CreateFlowMap(((DevExpress.XtraEditors.SimpleButton)sender).Name.ToString().Trim(), ((DevExpress.XtraEditors.SimpleButton)sender).Text.ToString().Trim());
}

创建流程图部分方法如下(有需要源码可关注作者公众号,私信作者免费获取):

//创建流程图
public void CreateFlowMap(string sModelID, string sModelName)
{
//查找是否存在流程图
string sFilter = "sModelCode = '" + sModelID + "'";
TabControl2.Visible = true;
Boolean bExists = false;
//查找模块流程图是否存在
foreach (DevExpress.XtraTab.XtraTabPage tabPage in TabControl2.TabPages)
{
if (tabPage.Name == sModelID)
{
tabPage.PageVisible = true;
TabControl2.SelectedTabPage = tabPage;
bExists = true;
}
else
{
tabPage.PageVisible = false;
}
}
//不存在需要增加页面
if (!bExists)
{
.....

You say a JB without pictures !无图言X,先给大家看看设计图

图片展示解析:

1.左侧栏初始化动作,加载所有系统模块

2.右侧上部分为操作栏,设计按钮处理当前选中的菜单模块,用于加载/新增/删除当前模块的流程图

3.右侧左边部分为绘制工具栏,此处只拿绘制直线(或带箭头的直线),Label(流程注释),按钮来举例子。

4.右侧下部分为绘制工具栏的属性配置,点击保存,呈现绘制结果如图右侧中间部分

5.流程图展示区,用于加载或绘制流程图

(以上因篇幅和时间限制未做详细测试,主要实现功能为主举个例子,作者绘制期间也有遇到不完善的地方,后续有时间在优化)

代码没有太大难度(需要源码研究可关注作者公众号,私信作者免费获取),主要跟大家分享下绘制流程模块吧。

(带箭头的)直线的绘制  

Talk is Cheap,直接上代码:

  KzxLine line = new KzxLine();

  bAddLine = true;
line.Name = "Line";
line.Tag = "";
line.lineWidth = int.Parse(this.cmb_LineWidth.Text.ToString());
string sColor = this.cmb_ColorLine.Text.ToString().Trim();
switch (sColor)
{
case "Black":
line.LineColor = KzxLine.ColorType.Black;
break;
case "Blue":
line.LineColor = KzxLine.ColorType.Blue;
break;
case "Green":
line.LineColor = KzxLine.ColorType.Green;
break;
case "Lime":
line.LineColor = KzxLine.ColorType.Lime;
break;
case "Red":
line.LineColor = KzxLine.ColorType.Red;
break;
case "Yellow":
line.LineColor = KzxLine.ColorType.Yellow;
break;
default:
line.LineColor = KzxLine.ColorType.Black;
break;
}
line.IsSolid = !this.chk_Solid.Checked;
switch (this.cmb_ArrowType.Text.ToString().Trim())
{
case "Start":
line.ArrowPosition = KzxLine.ArrowType.Start;
break;
case "End":
line.ArrowPosition = KzxLine.ArrowType.End;
break;
case "All":
line.ArrowPosition = KzxLine.ArrowType.All;
break;
case "None":
line.ArrowPosition = KzxLine.ArrowType.None;
break;
}
if (this.chk_Horizon.Checked)
{
line.LineStyle = KzxLine.LineType.Horizontal;
line.Left = int.Parse(this.edt_LeftLine.Text.ToString());
line.Top = int.Parse(this.edt_TopLine.Text.ToString());
line.Width = int.Parse(this.edt_WidthLine.Text.ToString());
line.Height = int.Parse(this.cmb_LineWidth.Text.ToString()) * + ;
}
else
{
line.LineStyle = KzxLine.LineType.Vertical;
line.Left = int.Parse(this.edt_LeftLine.Text.ToString());
line.Top = int.Parse(this.edt_TopLine.Text.ToString());
line.Width = int.Parse(this.cmb_LineWidth.Text.ToString()) * + ;
line.Height = int.Parse(this.edt_HeightLine.Text.ToString());
}
line.Visible = true; line.Click += onClick;
MoveClass.BarcodeControl(line);
if (bFirstControl)
{
MoveClass.BarcodeCreate();
bFirstControl = false;
}
this.TabControl2.Enabled = true;
this.TabControl1.SelectedTabPage = TabPage3;
this.TabPage3.PageVisible = true; this.kzxsBtnAddButton.Enabled = true;
this.kzxsBtnAddLabel.Enabled = true;
this.kzxsBtnAddLine.Enabled = true;

其中KzxLine是作者封装的用户控件,(如有需要,请关注公众号私信作者,源码免费赠送)部分代码如下:

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//e.Graphics.DrawLine(new Pen(lineColor, lineHeight), 1, 1, this.Width, lineHeight); AdjustableArrowCap lineCap = new AdjustableArrowCap(, , true);
Pen p = new Pen(lineColor, ); string sColor = "";
if ((int)color == )
{
sColor = "Black";
}
if ((int)color == )
{
sColor = "Red";
}
if ((int)color == )
{
sColor = "Yellow";
}
if ((int)color == )
{
sColor = "Blue";
}
if ((int)color == )
{
sColor = "Green";
}
if ((int)color == )
{
sColor = "Lime";
} p.Color = Color.FromName(sColor);
p.Width = LWidth; if ((int)ArrowP == )
{
p.CustomStartCap = lineCap;
}
else
if ((int)ArrowP == )
{
p.CustomEndCap = lineCap;
}
else
if ((int)ArrowP == )
{
p.CustomStartCap = lineCap;
p.CustomEndCap = lineCap;
} if (!Solid)
{
float[] dashValues = { , , , };
p.DashPattern = dashValues;
} int iLeft = ;
int iTop = ;
int iWidth = ;
int iHeight = ; if ((int)sTyle == )
{
iLeft = ;
iTop = LWidth * + ;
iWidth = this.Width;
iHeight = LWidth * + ;
}
else
{
iLeft = LWidth * + ;
iTop = ;
iWidth = LWidth * + ;
iHeight = this.Height;
}
e.Graphics.DrawLine(p, iLeft, iTop, iWidth, iHeight);
p.Dispose();
}

点击如图"箭头/直线"按钮后,下面会显示控件的属性配置区域,设置好后点击保存,就会把绘制好的控件添加到流程图展示区。保存事件如下:

private void Btn_SaveLine_Click(object sender, EventArgs e)
{
if (bAddLine)
{
KzxLine line = new KzxLine(); line.Name = "Line";
line.Tag = "";
line.lineWidth = int.Parse(this.cmb_LineWidth.Text.ToString());
string sColor = this.cmb_ColorLine.Text.ToString().Trim();
switch (sColor)
{
case "Black":
line.LineColor = KzxLine.ColorType.Black;
break;
case "Blue":
line.LineColor = KzxLine.ColorType.Blue;
break;
case "Green":
line.LineColor = KzxLine.ColorType.Green;
break;
case "Lime":
line.LineColor = KzxLine.ColorType.Lime;
break;
case "Red":
line.LineColor = KzxLine.ColorType.Red;
break;
case "Yellow":
line.LineColor = KzxLine.ColorType.Yellow;
break;
default:
line.LineColor = KzxLine.ColorType.Black;
break;
}
line.IsSolid = !this.chk_Solid.Checked;
switch (this.cmb_ArrowType.Text.ToString().Trim())
{
case "Start":
line.ArrowPosition = KzxLine.ArrowType.Start;
break;
case "End":
line.ArrowPosition = KzxLine.ArrowType.End;
break;
case "All":
line.ArrowPosition = KzxLine.ArrowType.All;
break;
case "None":
line.ArrowPosition = KzxLine.ArrowType.None;
break;
}
if (this.chk_Horizon.Checked)
{
line.LineStyle = KzxLine.LineType.Horizontal;
line.Left = int.Parse(this.edt_LeftLine.Text.ToString());
line.Top = int.Parse(this.edt_TopLine.Text.ToString());
line.Width = int.Parse(this.edt_WidthLine.Text.ToString());
line.Height = int.Parse(this.cmb_LineWidth.Text.ToString()) * + ;
}
else
{
line.LineStyle = KzxLine.LineType.Vertical;
line.Left = int.Parse(this.edt_LeftLine.Text.ToString());
line.Top = int.Parse(this.edt_TopLine.Text.ToString());
line.Width = int.Parse(this.cmb_LineWidth.Text.ToString()) * + ;
line.Height = int.Parse(this.edt_HeightLine.Text.ToString());
}
line.Visible = true; line.Click += onClick;
MoveClass.BarcodeControl(line);
if (bFirstControl)
{
MoveClass.BarcodeCreate();
bFirstControl = false;
}
this.TabControl2.Enabled = true;
bAddLine = false; TabControl2.SelectedTabPage.Controls.Add(line);
this.kzxsBtnAddButton.Enabled = true;
this.kzxsBtnAddLabel.Enabled = true;
this.kzxsBtnAddLine.Enabled = true;
this.sBtnDelete.Enabled = true;
}
else if ((selectControl is KzxLine) && (KzxLine)selectControl != null)
{
((KzxLine)selectControl).lineWidth = int.Parse(this.cmb_LineWidth.Text.ToString());
string sColor = this.cmb_ColorLine.Text.ToString().Trim();
switch (sColor)
{
case "Black":
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Black;
break;
case "Blue":
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Blue;
break;
case "Green":
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Green;
break;
case "Lime":
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Lime;
break;
case "Red":
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Red;
break;
case "Yellow":
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Yellow;
break;
default:
((KzxLine)selectControl).LineColor = KzxLine.ColorType.Black;
break;
}
((KzxLine)selectControl).IsSolid = !this.chk_Solid.Checked;
switch (this.cmb_ArrowType.Text.ToString().Trim())
{
case "Start":
((KzxLine)selectControl).ArrowPosition = KzxLine.ArrowType.Start;
break;
case "End":
((KzxLine)selectControl).ArrowPosition = KzxLine.ArrowType.End;
break;
case "All":
((KzxLine)selectControl).ArrowPosition = KzxLine.ArrowType.All;
break;
case "None":
((KzxLine)selectControl).ArrowPosition = KzxLine.ArrowType.None;
break;
}
if (this.chk_Horizon.Checked)
{
((KzxLine)selectControl).LineStyle = KzxLine.LineType.Horizontal;
((KzxLine)selectControl).Left = int.Parse(this.edt_LeftLine.Text.ToString());
((KzxLine)selectControl).Top = int.Parse(this.edt_TopLine.Text.ToString());
((KzxLine)selectControl).Width = int.Parse(this.edt_WidthLine.Text.ToString());
((KzxLine)selectControl).Height = int.Parse(this.cmb_LineWidth.Text.ToString()) * + ;
}
else
{
((KzxLine)selectControl).LineStyle = KzxLine.LineType.Vertical;
((KzxLine)selectControl).Left = int.Parse(this.edt_LeftLine.Text.ToString());
((KzxLine)selectControl).Top = int.Parse(this.edt_TopLine.Text.ToString());
((KzxLine)selectControl).Width = int.Parse(this.cmb_LineWidth.Text.ToString()) * + ;
((KzxLine)selectControl).Height = int.Parse(this.edt_HeightLine.Text.ToString());
}
}
}

因所有绘制控件都绑定了拖拽事件,所以可以在流程图展示区随意拖拽部署显示控件(效果见下图)。

Label(注释)控件封装

  /// <summary>
/// 标签验证
/// </summary>
public partial class KzxLabel : KzxBaseControl

Label无需重绘只需封装,初始化绑定多语言即可。

  public void LayoutControl()
{
BindingEvent(this, PluginInfoTable);
if (this.DesignMode == true)
{
this.DesigeCaption = GetLanguage(this.MessageCode, this.DesigeCaption);
}
} /// <summary>
/// 绑定事件
/// </summary>
/// <param name="eventInfoTable">事件信息表</param>
public override void BindingEvent(DataTable eventInfoTable)
{
BindingEvent(this, eventInfoTable);
} private void KzxLabel_Load(object sender, EventArgs e)
{
LayoutControl();
//UpdateDelegate d = LayoutControl;
//this.BeginInvoke(d);
}

按钮控件封装

按钮的封装同上Label一样,具体请移步《玩转控件:扩展Dev中SimpleButton》.或者直接用Dev原生的SimpleButton亦可,此处不做过多废话。只需在属性配置区域的保存事件中,添加到流程图展示区即可,配置区的按钮保存代码如下:

 BillInfo info = new BillInfo();
//info.sID = Edt_FrmBtn.EditValue.ToString();
info.sFrmName = Edt_FrmBtn.Text.ToString();
info.sFrmCaption = Edt_CaptionBtn.Text.Trim();
info.sMsgID = Edt_MsgBtn.Text.ToString().Trim(); if (bAddBtn)
{
DevExpress.XtraEditors.SimpleButton sb = new DevExpress.XtraEditors.SimpleButton();
sb.Left = int.Parse(Edt_LeftBtn.Text.Trim());
sb.Top = int.Parse(Edt_TopBtn.Text.Trim());
sb.Width = int.Parse(Edt_WidthBtn.Text.Trim());
sb.Height = int.Parse(Edt_HightBtn.Text.Trim());
sb.Name = Edt_FrmBtn.Text.Trim();
sb.Text = Edt_CaptionBtn.Text.Trim(); sb.Tag = info; sb.Image = picture1.Image;
sb.ImageLocation = DevExpress.XtraEditors.ImageLocation.TopCenter;
sb.Cursor = Cursors.Hand;
sb.Visible = true;
TabControl2.SelectedTabPage.Controls.Add(sb); sb.Click += onClick;
MoveClass.BarcodeControl(sb);
if (bFirstControl)
{
MoveClass.BarcodeCreate();
bFirstControl = false;
}
this.TabControl2.Enabled = true;
bAddBtn = false; this.kzxsBtnAddButton.Enabled = true;
this.kzxsBtnAddLabel.Enabled = true;
this.kzxsBtnAddLine.Enabled = true;
}
else if ((selectControl is DevExpress.XtraEditors.SimpleButton) && (DevExpress.XtraEditors.SimpleButton)selectControl != null)
{
((DevExpress.XtraEditors.SimpleButton)selectControl).Left = int.Parse(Edt_LeftBtn.Text.Trim());
((DevExpress.XtraEditors.SimpleButton)selectControl).Top = int.Parse(Edt_TopBtn.Text.Trim());
((DevExpress.XtraEditors.SimpleButton)selectControl).Width = int.Parse(Edt_WidthBtn.Text.Trim());
((DevExpress.XtraEditors.SimpleButton)selectControl).Height = int.Parse(Edt_HightBtn.Text.Trim());
((DevExpress.XtraEditors.SimpleButton)selectControl).Name = Edt_FrmBtn.Text.Trim();
((DevExpress.XtraEditors.SimpleButton)selectControl).Text = Edt_CaptionBtn.Text.Trim(); ((DevExpress.XtraEditors.SimpleButton)selectControl).Tag = info;
((DevExpress.XtraEditors.SimpleButton)selectControl).Image = picture1.Image;
((DevExpress.XtraEditors.SimpleButton)selectControl).ImageLocation = DevExpress.XtraEditors.ImageLocation.TopCenter;
((DevExpress.XtraEditors.SimpleButton)selectControl).Cursor = Cursors.Hand;
}

以上便是"箭头/直线","Label注释","按钮"等功能的准备工作,具体效果如图:

再次强调,因时间和篇幅问题,作者没有对代码做严格的校验,主要以实现功能为主。所以当您拿到源码时需要根据实际情况自行完善,或者后续作者有时间也会继续完善(工作996+的我太难了!)

各个模块功能实现后,就是保存当前绘制的流程图环节了,为了演示效果,作者没有处理数据库相关的工作,主要以DataTable来存储相关绘制数据的。至于图片,作者是用流的方式来存储的,展示时解析即可。

#region 图片处理
/// <summary>
/// 点击上传图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void picture1_Click(object sender, EventArgs e)
{
if (this.openDialog1.ShowDialog() == DialogResult.OK)
{
picture1.Image = Image.FromFile(this.openDialog1.FileName);
}
}
/// <summary>
/// 用流的方式来存储图片
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
private byte[] convertByte(Image img)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, img.RawFormat);
byte[] bytes = ms.ToArray();
ms.Close();
return bytes;
}
private Image convertImg(byte[] datas)
{
MemoryStream ms = new MemoryStream(datas);
Image img = Image.FromStream(ms, true);
ms.Close();
return img;
} #endregion

DataTable数据存储如下图:

大家可以根据自己实际情况,存储到数据库或者配置文件中,具体保存代码如下:

 int iOrder = ;
foreach (Control c in TabControl2.SelectedTabPage.Controls)
{
//string sID = "";
string sFrmName = "";
string sCaption = "";
string sType = "";
string sBtnPositon = "";
string sArrowType = "";
string sFrmType = "";
string sMsgID = "";
string sColor = "";
Boolean bSolid = true;
Boolean bUnderLine = false;
Boolean bHorzion = true; int iLeft = ;
int iTop = ;
int iWidth = ;
int iHeight = ;
int iLineWidth = ;
float iFontSize = ;
BillInfo info = c.Tag as BillInfo; if (c is DevExpress.XtraEditors.SimpleButton)
{
//Button按钮
//sID = info.sID;
sFrmName = c.Name.ToString().Trim();
sCaption = c.Text.ToString().Trim();
sFrmType = info.sFrmType;
sMsgID = info.sMsgID;
sType = "Btn";
iLeft = c.Left;
iTop = c.Top;
iWidth = c.Width;
iHeight = c.Height;
sBtnPositon = "TopCenter";
}
else if (c is DevExpress.XtraEditors.LabelControl)
{
//Label控件
//sID = info.sID;
sFrmName = c.Name.ToString().Trim();
sCaption = c.Text.ToString().Trim();
sFrmType = info.sFrmType;
sMsgID = info.sMsgID;
sType = "Label";
iLeft = c.Left;
iTop = c.Top;
iWidth = c.Width;
iHeight = c.Height; if (c.Font.Underline) //下划线
{
bUnderLine = true;
}
iFontSize = ((DevExpress.XtraEditors.LabelControl)c).Font.Size; //字体大小
sColor = ((DevExpress.XtraEditors.LabelControl)c).ForeColor.Name.ToString(); //字体颜色 }
else if (c is KzxLine)
{
sCaption = "Line";
sType = "Line";
if (((KzxLine)c).ArrowPosition == KzxLine.ArrowType.Start)
{
sArrowType = "Start";
}
else if (((KzxLine)c).ArrowPosition == KzxLine.ArrowType.End)
{
sArrowType = "End";
}
else if (((KzxLine)c).ArrowPosition == KzxLine.ArrowType.All)
{
sArrowType = "All";
}
else if (((KzxLine)c).ArrowPosition == KzxLine.ArrowType.None)
{
sArrowType = "None";
}
//颜色
if (((KzxLine)c).LineColor == KzxLine.ColorType.Black)
{
sColor = "Black";
}
else if (((KzxLine)c).LineColor == KzxLine.ColorType.Blue)
{
sColor = "Blue";
}
else if (((KzxLine)c).LineColor == KzxLine.ColorType.Green)
{
sColor = "Green";
}
else if (((KzxLine)c).LineColor == KzxLine.ColorType.Lime)
{
sColor = "Lime";
}
else if (((KzxLine)c).LineColor == KzxLine.ColorType.Red)
{
sColor = "Red";
}
else if (((KzxLine)c).LineColor == KzxLine.ColorType.Yellow)
{
sColor = "Yellow";
}
else if (((KzxLine)c).LineColor == KzxLine.ColorType.Black)
{
sColor = "Black";
}
iLineWidth = ((KzxLine)c).lineWidth; if (!((KzxLine)c).IsSolid)
{
bSolid = false;
} if (((KzxLine)c).LineStyle == KzxLine.LineType.Horizontal)
{
bHorzion = true;
iLeft = ((KzxLine)c).Left;
iTop = ((KzxLine)c).Top + ((KzxLine)c).lineWidth * + ;
iWidth = ((KzxLine)c).Width + ((KzxLine)c).Left;
iHeight = ((KzxLine)c).Top + ((KzxLine)c).lineWidth * + ;
}
else
{
bHorzion = false;
iLeft = ((KzxLine)c).Left + ((KzxLine)c).lineWidth * + ;
iTop = ((KzxLine)c).Top;
iWidth = ((KzxLine)c).Left + ((KzxLine)c).lineWidth * + ;
iHeight = ((KzxLine)c).Top + ((KzxLine)c).Height;
} //gc[i] = c;
} if ((c is DevExpress.XtraEditors.SimpleButton) || (c is DevExpress.XtraEditors.LabelControl)
|| (c is KzxLine))
{
DataRow newRow = dtDesign.NewRow();
newRow["uGuid"] = Guid.NewGuid().ToString("D");
newRow["sModelCode"] = sModel;
//newRow["sID"] = sID;
newRow["sFrmName"] = sFrmName;
newRow["sCaption"] = sCaption;
newRow["sType"] = sType;
newRow["iLeft"] = iLeft;
newRow["iTop"] = iTop;
newRow["iWidth"] = iWidth;
newRow["iHeight"] = iHeight;
newRow["sBtnPositon"] = sBtnPositon;
newRow["sArrowType"] = sArrowType;
if (c is DevExpress.XtraEditors.SimpleButton)
{
if (((DevExpress.XtraEditors.SimpleButton)c).Image != null)
newRow["mImage"] = convertByte(((DevExpress.XtraEditors.SimpleButton)c).Image);
}
else
{
newRow["mImage"] = null;
}
//newRow["mImage"] = sModel;
newRow["iOrder"] = iOrder;
newRow["bActive"] = ;
newRow["sFrmType"] = sFrmType;
newRow["sMsgID"] = sMsgID;
newRow["sColor"] = sColor;
newRow["iLineWidth"] = iLineWidth;
newRow["iFontSize"] = iFontSize;
newRow["sSysMode"] = "";
newRow["bSolid"] = bSolid;
newRow["bUnderLine"] = bUnderLine;
newRow["bHorizon"] = bHorzion;
dtDesign.Rows.Add(newRow); iOrder = iOrder + ;
}
} //TODO:保存到数据库操作 this.Btn_SaveButton.Enabled = false;
this.Btn_SaveLabel.Enabled = false;
this.Btn_SaveLine.Enabled = false; bDesign = false;
bAddBtn = false;
bAddLabel = false;
bAddLine = false; this.Btn_Design.Enabled = true;
this.Btn_Post.Enabled = false;
this.kzxsBtnAddButton.Enabled = false;
this.kzxsBtnAddLabel.Enabled = false;
this.kzxsBtnAddLine.Enabled = false;
this.Btn_Cancel.Enabled = false; this.TabControl2.Enabled = true; //TODO:从数据库加载数据流并绑定数据 this.TabControl2.TabPages.Remove(this.TabControl2.SelectedTabPage);
CreateFlowMap(sModel, sModelName);

如上代码TODO出需要根据自己实际完善,或者公众号私信作者一起探讨。

至此工作完成!一起来看看最终效果:

由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号联系博主,源码可以免费赠予~!有疑问的也可以CALL我一起探讨。

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

玩转控件:Fucking ERP之流程图的更多相关文章

  1. 玩转控件:GDI+动态绘制流程图

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

  2. 玩转控件:重写/重绘Dev中MessageBox弹窗控件

    很久没有更新博客了,本想着直接发一篇<手撕ERP>系列,从控件重写.重绘,到框架搭建,再到部分模块实现+业务的.但是每次动手的时候,都觉得难以下手.直接从数据库设计开始吧,模块设计还没定下 ...

  3. 玩转控件:扩展Dev中SimpleButton

    何为扩展,顾名思义,就是在原有控件属性.事件的基础上拓展自己需要或实用的属性.事件等等.或者可以理解为,现有的控件已经不能完全满足我(的需求)了.好的扩展会使控件更加完善,实用,好用.不好的扩展,说白 ...

  4. 玩转控件:重绘DEVEXPRESS中DateEdit控件 —— 让DateEdit支持只选择年月 (提供源码下载)

      前言 上一篇博文<玩转控件:重绘ComboBox —— 让ComboBox多列显示>中,根据大家的回馈,ComboBox已经支持筛选了,更新见博文最后最后最后面.   奇葩 这两天遇到 ...

  5. 玩转控件:封装Dev的LabelControl和TextEdit

    俗话说的好:"工欲善其事必先利其器",作为软件攻城狮也是同样道理,攻城狮开发的软件目的是简化客户的操作,让客户动动手指就可以完成很多事情,减少人力成本.这也是系统/软件存在的目的. ...

  6. 玩转控件:封装Dev的SearchLookupEdit

    鸣谢 随着前面几个章节对控件封装与扩展的分享,不少小伙伴儿们在作者公众号上反馈,并联系作者,表示通过这些系列和源码能学到不少细节上的东西,并运用到了自己的实际项目当中,也有不少伙伴儿反馈更好更优的处理 ...

  7. 玩转控件:对Dev的GridControl控件扩展

    缘由 一切实现来源于需求,目的在于不盲目造轮子,有小伙伴儿在看了<玩转控件:对Dev中GridControl控件的封装和扩展>文章后,私信作者说,因公司业务逻辑比较复杂,展示字段比较多,尤 ...

  8. 玩转控件:对Dev中GridControl控件的封装和扩展

    又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动.... 转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠.裁员的裁员,降薪的降薪,996的996~~说起来都是泪,以 ...

  9. 慧都十年大促起幕,Dev、BCG等明星控件6.8折起!

    2013慧都十周年大促正式起幕,DevExpress.BCGControlBar.FastReport.TeeChart等精选明星控件Top 10悉数"价"到,还有更多产品惊喜&q ...

随机推荐

  1. Java并发包下锁学习第一篇:介绍及学习安排

    Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...

  2. Android 文章合集 200+ 篇

    code小生 一个专注大前端领域的技术平台 公众号回复Android加入安卓技术群 镇楼 2017 文章合集 2017 年度文章分类整理 下面是 2018 年公众号所发表的文章分类整理 面经 一年经验 ...

  3. leetcode 876. 链表的中间结点 签到

    题目: 给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3,4,5] 输出:此列表中的结点 3 (序列化形式: ...

  4. AI领域:如何做优秀研究并写高水平论文?

    来源:深度强化学习实验室 每个人从本科到硕士,再到博士.博士后,甚至工作以后,都会遇到做研究.写论文这个差事.论文通常是对现有工作的一个总结和展示,特别对于博士和做研究的人来说,论文则显得更加重要. ...

  5. 面试刷题29:mysql事务隔离实现原理?

    mysql的事务是innodb存储引擎独有的,myisam存储引擎不支持事务. 事务最经典的例子就是转账了,事务要保证的是一组数据库的操作要么全部成功,要么全部失败.是为了保证高并发场景下数据的正确性 ...

  6. 如何查看自己项目中vue的版本号和cli的版本号

    查看Vue版本号 代码方式 npm list vue 其他方式 找到package.json文件夹 找"dependencies"然后就可以看到你装的vue的版本了 查看cli版本 ...

  7. 7.Maven命令

    在eclipse中运行maven 一.首先要对pom.xml文件右键→Run As→Maven build 二.输入Maven命令 三.常见的Maven命令有: [1]clean 清理 [2]comp ...

  8. 如何找回QQ聊天记录、语音、图片?

    多图长图预警,本教程适用于 安卓手机 认真仔细看完答案的成功几率翻倍哟! 请各位认真看答案!求您了~ 2020年/4/4日 更新 人民不会忘记,祖国不会忘记,我们不会忘记,先烈不朽. 调整答案顺序,使 ...

  9. Java数组模拟队列

    队列 先进先出 什么意思呢? 我的理解:队列就是一个数组(不包含链表),然后我们给它施加一个存数据和取数据的规则 当只允许从一端存数据,从另一端取数据的数组,就是队列,我们要做的就是给这个数组施加我们 ...

  10. PTA数据结构与算法题目集(中文) 7-36 社交网络图中结点的“重要性”计算 (30 分)

    PTA数据结构与算法题目集(中文)  7-36 社交网络图中结点的“重要性”计算 (30 分) 7-36 社交网络图中结点的“重要性”计算 (30 分)   在社交网络中,个人或单位(结点)之间通过某 ...