国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C#如何實現一個簡單的流程圖設計器

2019-11-14 13:49:42
字體:
來源:轉載
供稿:網友

  以前看過不少Window Form開發的流程圖設計器,支持節點拖放,非常方便即可設計出很美觀的流程圖,作為一個程序員,對其內部實現原理一直很好奇,感嘆有朝一日自己如果可以開發一款類似的軟件那是多么讓人興奮的事情呀!自從有了這樣的想法,一直都在積累和學習這方面的知識,最近一個偶然的機會竟然實現了一個簡單的流程圖設計器(雖然其功能還有很多不完善之處,但是心中還是非常高興,滿滿的成就感)。

  話不多說,先看一下實現的主界面效果:

左邊是一個ListView(listView1),右邊的畫布是一個Panel(panel1)。下面將主要思路介紹如下:

  1)允許拖放,listView1和panel1設置其AllowDrop=true;

  2)非連接線類型的圖形拖放處理:左邊的listView1的項目被選中后,可以獲取其圖形類型(是路由器、是服務器還是云等),并在全局變量中記錄下當前的操作對象類型,然后拖放到panel1后,panel1獲得對應的圖形類型,首先判斷圖的類型是否為非連接線,如果是則獲取對應的圖片,用g.DrawImage將其繪制到畫布中,圖片的坐標參考自當前鼠標(拖放到panel1最后松開鼠標左鍵時的坐標)的坐標。

  3)連接線類型的圖形處理:如果是連接線,應該要有兩個點來確定一條直線。當選中listView1的連接線時,會在全局變量中記錄下當前的操作對象類型是連接線,當在panel1上單擊時,首選判斷當前的操作對象類型的全局對象是否為連接線,如果是,則記錄第一次單擊的點,然后等待記錄單擊的第二個點,當第二次單擊完成后,調用繪制直線的方法在畫布中進行繪制直線。

  4)當線和圖形綁定后,拖放圖形時,直線附屬在圖形的那個點會隨著圖形位置的變化而變化,當最后定位后,panel1會重繪網格和流程圖。

  5)編輯圖形信息:在panel1上雙擊時,程序獲取雙擊的坐標點離所有的圖形區域中最近的圖形,然后計算距離,看是否滿足設置的閾值,如果小于閾值,則認為是在該圖形上雙擊,是要進行編輯操作。

下面給出繪制網格的代碼:

 1         /// <summary> 2         /// 繪制網格 3         /// </summary> 4         PRivate void renderGrid() 5         { 6             //全局變量存儲最大最小值,作為繪制區域 7             Graphics g = this.panel1.CreateGraphics(); 8             Color color = Color.DarkGray; 9             Pen p = new Pen(color, 1);10             p.DashStyle = DashStyle.Dash;11             for (int x = 0; x <= this.panel1.Width; x = x + 20)12             {13                 PointF p1 = new PointF(x, 0);14                 PointF p2 = new PointF(x, Height);15                 g.DrawLine(p, p1, p2);16             }17 18             for (int y = 0; y <= panel1.Height; y = y + 20)19             {20                 PointF p1 = new PointF(0, y);21                 PointF p2 = new PointF(Width, y);22                 g.DrawLine(p, p1, p2);23 24             }25 26         }
View Code

 下面給出在panel1上進行鼠標單擊的處理程序:

 1        private void panel1_MouseClick(object sender, MouseEventArgs e) 2         { 3             int X = e.X; 4             int Y = e.Y; 5             if (this.__gObjType== "") 6             { 7                 return; 8             } 9             if (this.__gObjType != "Line")10             {11                 AddObjectFromMouseLocation(X, Y, 0, 0, this.__gObjType);12             }13             else14             {15                 //line16                 if (__lineMouseClickedCount == 1)17                 {18                     __lineX2 = e.X;19                     __lineY2 = e.Y;20                     AddObjectFromMouseLocation(__lineX1, __lineY1, __lineX2, __lineY2, this.__gObjType);21 22                     //連接線方向判斷23                     __lineMouseClickedCount = 0;24                     __lineX1 = 0;25                     __lineY1 = 0;26                     __lineX2 = 0;27                     __lineY2 = 0;28                 }29                 else if (__lineMouseClickedCount == 0)30                 {31                     __lineX1 = e.X;32                     __lineY1 = e.Y;33                     __lineMouseClickedCount = 1;34                 }35                 else36                 {37                     __lineMouseClickedCount = 0;38                     __lineX1 = 0;39                     __lineY1 = 0;40                     __lineX2 = 0;41                     __lineY2 = 0;42                 }43 44             }45         }
View Code

下面給出重繪的程序:

 1        private void ReDrawAll() 2         { 3             renderGrid(); 4             Graphics g = this.panel1.CreateGraphics(); 5             g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 6             GObject CurrObj = new GObject(); 7             Rectangle Rct = new Rectangle(); 8             Pen p = new Pen(Color.Black); 9             //p.Width = 2;10             p.Width = __penWidth * __zoomTimes;11 12             Image ObjImg;13             int xm = 0;14             int ym = 0;15 16             int _maxX = 0;17             int _maxY = 0;18             int _minX = 0;19             int _minY = 0;20             int _oldW = this.panel1.Width;21             int _oldH = this.panel1.Height;22 23             string IsLine = "";24             //Nobj==50為當前畫布最大的對象個數25             for (int i = 0; i < GNetworkFlow.Nobj; i++)26             {27                 CurrObj = GNetworkFlow.GObjects[i];28                 //當前對象類型判斷29                 if (CurrObj.Type == "") IsLine = "N/D";30                 if (CurrObj.Type == "Line") IsLine = "Y";31                 if ((CurrObj.Type != "Line") && (CurrObj.Type != "")) IsLine = "N";32                 //33                 #region old panel1作為畫布,將其嵌套在panel2中實現超出邊界出現滾動條34 35                 if (_maxX < CurrObj.x2)36                 {37                     _maxX = CurrObj.x2;38                 }39                 if (_maxY < CurrObj.y2)40                 {41                     _maxY = CurrObj.y2;42                 }43                 if (_minX > CurrObj.x1)44                 {45                     _minX = CurrObj.x1;46                 }47                 if (_minY > CurrObj.y1)48                 {49                     _minY = CurrObj.y1;50                 }51 52 53 54                 if (_oldW < _maxX - _minX)55                 {56                     this.panel1.Width = _maxX - _minX;57                 }58                 if (_oldH < _maxY - _minY)59                 {60                     this.panel1.Height = _maxY - _minY;61                 }62                 if (this.panel1.Height < this.panel2.Height)63                 {64                     this.panel1.Height = this.panel2.Height;65                 }66                 if (this.panel1.Width < this.panel2.Width)67                 {68                     this.panel1.Width = this.panel2.Width;69                 }70 71                 #endregion72 73 74                 switch (IsLine)75                 {76                     case "Y":77                         arrow.DrawArrow(g, p, p.Brush, CurrObj.x1, CurrObj.y1, CurrObj.x2, CurrObj.y2);78                         xm = (CurrObj.x1 + CurrObj.x2) / 2;79                         ym = (CurrObj.y1 + CurrObj.y2) / 2;80                         AddText(xm, ym, CurrObj.Name, false);81                         break;82                     case "N":83                         Rct.X = CurrObj.x1;84                         Rct.Y = CurrObj.y1;85                         Rct.Width = CurrObj.x2 - CurrObj.x1;86                         Rct.Height = CurrObj.y2 - CurrObj.y1;87                         if (CurrObj.Type != String.Empty)88                         {89                             ObjImg = FindGObjectTypeImage(CurrObj.Type);90                             g.DrawImage(ObjImg, Rct);91                             AddText(CurrObj.x1, CurrObj.y1, CurrObj.Name, true);92                             GNetworkFlow.AdjustLinkedTo(CurrObj.Name);93                         }94                         break;95                 }96             }97 98         }
View Code

下面將繼續完善以下幾個功能:

1)序列化:可以將圖形序列化和反序列化,將序列化的信息保存到數據庫,也可以從數據庫加載圖形;

2)圖形節點必須要附加其他屬性和方法,為流程記錄更多的信息、例如權限配置、當前處理的人、下一步是什么節點等;

3)繪圖功能的加強,繪圖可以動態修改顏色,這樣可以區分流程在不同節點的顏色顯示;

4)布局優化算法,能否根據畫布大小,自動排列圖形...

今天又將界面做了美化,界面如下:


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 库伦旗| 邵阳县| 清水县| 潜山县| 长沙县| 清远市| 合肥市| 巴林右旗| 安顺市| 离岛区| 嘉义县| 藁城市| 新巴尔虎左旗| 万年县| 曲麻莱县| 万年县| 阿图什市| 望江县| 瑞丽市| 于田县| 蛟河市| 科技| 额济纳旗| 延寿县| 兰州市| 通化市| 平陆县| 尚义县| 山东省| 扶沟县| 南陵县| 广宗县| 禄劝| 托克逊县| 永泰县| 思南县| 湾仔区| 龙口市| 阿勒泰市| 卓资县| 神池县|