轉(zhuǎn)帖|使用教程|編輯:龔雪|2022-07-29 10:06:15.140|閱讀 634 次
概述:本文主要為大家介紹如何使用DevExpress控件進行流程圖形的繪制和控制,歡迎下載產(chǎn)品體驗!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
DevExpress提供了一個比較強大的圖形繪制工具,可以用于繪制各種圖形,如流程圖、組織機構(gòu)圖等等,本篇隨筆介紹XtraDiagram.DiagramControl的使用,以及利用代碼對其屬性進行控制,以及利用圖形模具的自定義操作,實現(xiàn)一些簡單流程圖形的繪制和處理。
DiagramControl是類似Visio的繪圖控件,以前我2006年的就接觸使用Visio的二次開發(fā),當(dāng)時開始還是利用VB6 + VIsio2003進行二次開發(fā)的,后來把它改良為C# + Visio進行二次開發(fā),DiagramControl的對象模型很類似Visio的相關(guān)對象模型,如對于工具欄的形狀,稱之為模具(Stencil),Visio也是稱之為Stencil, DiagramControl里面的很多接口名稱依舊采用Stencil進行命名,因此估計也是借鑒了很多Visio的對象設(shè)計知識。
DiagramControl是一個界面控件,類似Visio SDK里面的DrawingControl的存在,可以通過它進行圖形的繪制,各種窗口的顯示和隱藏,以及跟蹤各種事件的處理。
DiagramControl控件拖動到窗體中后,會自動增加一些屬性窗口,上排的繪圖工具中的按鈕是我添加的,用來測試該控件的一些屬性的控制。
1)屬性窗口的顯示和隱藏(折疊)
這個通過控制diagramControl1.OptionsView.PropertiesPanelVisibility 屬性就可以實現(xiàn)對這個屬性窗口的控制了。
里面顯示一些系統(tǒng)位置和內(nèi)容信息,以及一些自定義信息的窗口,后面我會介紹如何自定義處理這些模具的屬性。
通過按鈕處理的代碼,我們可以實現(xiàn)對這個窗口的顯示或者隱藏處理。
//切換屬性窗口的顯示或關(guān)閉 var status = diagramControl1.OptionsView.PropertiesPanelVisibility; diagramControl1.OptionsView.PropertiesPanelVisibility = (status == PropertiesPanelVisibility.Visible ? PropertiesPanelVisibility.Collapsed : PropertiesPanelVisibility.Visible);
2)模具形狀窗口的顯示或隱藏
模具形狀的窗口,它是放在一個面板里面,我們只需要通過控制該面板的顯示或者隱藏就可以了,如下代碼所示。
//切換模具形狀窗口的顯示或關(guān)閉 var status = diagramToolboxDockPanel1.Visibility; diagramToolboxDockPanel1.Visibility = (status == DevExpress.XtraBars.Docking.DockVisibility.Visible ? DevExpress.XtraBars.Docking.DockVisibility.Hidden : DevExpress.XtraBars.Docking.DockVisibility.Visible);
或者通過控件的Toolbar屬性進行控制,一樣的效果。
//切換模具形狀窗口的顯示或關(guān)閉 var status = this.diagramControl1.OptionsView.ToolboxVisibility; this.diagramControl1.OptionsView.ToolboxVisibility = status == ToolboxVisibility.Closed ? ToolboxVisibility.Full : ToolboxVisibility.Closed;
3)放大縮小窗口的顯示或者隱藏
同樣我們也可以控制放大縮小窗口的顯示或者隱藏,它也是圖形繪制的一個常見的窗口。我們只需要判斷或者設(shè)置diagramControl1.OptionsView.ShowPanAndZoomPanel 屬性就可以了,如下代碼所示。
//切換放大縮小窗口的顯示或關(guān)閉 var status = diagramControl1.OptionsView.ShowPanAndZoomPanel; diagramControl1.OptionsView.ShowPanAndZoomPanel = !status;
4)其他屬性的處理
另外,我們可以通過控制一些屬性,實現(xiàn)對標(biāo)尺、網(wǎng)格、只讀視圖等模式進行控制。
//是否顯示標(biāo)尺 this.diagramControl1.OptionsView.ShowRulers = this.chkRuler.Checked; //是否顯示網(wǎng)格 this.diagramControl1.OptionsView.ShowGrid = this.chkGrid.Checked; //是否只讀視圖 this.diagramControl1.OptionsProtection.IsReadOnly = this.chkReadOnly.Checked;
在繪制圖形的時候,一般來說我們可能需要切換點選模式或者連接線模式,因此可以通過它的屬性ActiveTool進行設(shè)置。在點選模式下,可以對圖形進行拖動、放大縮小、旋轉(zhuǎn)等處理,連接線模式下,則會加亮連接點,便于自動繪制連接線。
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; }
當(dāng)然,我們也可以通過對鼠標(biāo)行為的分析來進行控制,如果鼠標(biāo)懸?;蛘叻胖迷趫D形上,就自動切換模式為連接線模式,否則為點選模式,那么只需要判斷鼠標(biāo)的移動行為即可自動處理,如下代碼所示。
/// <summary> /// 實現(xiàn)對圖形自動切換到連接點模式 /// </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); } }
最終案例的效果如下所示。
在實際的圖形繪制開發(fā)中,我們可以需要創(chuàng)建一些指定的形狀模具,那么我們弄好后一般可以存放在XML中,然后進行加載到控件上來,如下代碼就是注冊自定義的形狀的處理。
/// <summary> /// 注冊自定義的形狀。 /// 自定義圖形是以XML文件形式進行保存,圖形需要按照規(guī)定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); }
我們只需要設(shè)置選中的圖形就可以了,其他有需要的可以從More Shapes中選擇即可。
我們?nèi)绻枰趯傩源翱谥酗@示自定義的屬性,那么我們需要一些代碼開發(fā)才能實現(xiàn)。
我們首先需要繼承一個DiagramShape的子類,然后實現(xiàn)自己自定義的屬性定義,如下代碼所示。
對自定義屬性的處理,需要在事件中實現(xiàn)
diagramControl1.CustomGetEditableItemProperties += DiagramControl_CustomGetEditableItemProperties;
通過對它進行判斷可以實現(xiàn)自定義屬性的顯示處理
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"]); } }
然后我們可以注冊創(chuàng)建自己的模具形狀集合,如下代碼所示。
/// <summary> /// 創(chuàng)建自定義的模具 /// </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 集合中借用過來,構(gòu)建自己的自定義對象的,默認創(chuàng)建的對象是方形的。
如果我們需要動態(tài)構(gòu)建其他自定義類型,我們可以指定它的顏色等樣式,從而構(gòu)建不同類型的圖形。
//循環(huán)添加相關(guān)流程節(jié)點 var procNames = new List<string> { "審批", "歸檔", "閱辦", "會簽", "領(lǐng)導(dǎo)批示分閱"}; //定義幾個初始化顏色順序 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)); }
這樣就有不同顏色的圖形對象了。
根據(jù)這些我們就可以繪制出自己的各種流程圖了,并且也可以根據(jù)數(shù)據(jù)庫的信息,進行動態(tài)繪制展示。
DevExpress Universal Subscription擁有.NET開發(fā)需要的所有平臺控件,包含600多個UI控件、報表平臺、DevExpress Dashboard eXpressApp 框架、適用于 Visual Studio的CodeRush等一系列輔助工具。
屢獲大獎的軟件開發(fā)平臺DevExpress Universal 2022年第一個重要版本——v22.1已正式發(fā)布,該版本擁有眾多新產(chǎn)品和數(shù)十個具有高影響力的功能,可為桌面、Web和移動應(yīng)用提供直觀的解決方案,全面解決各種使用場景問題。
本文轉(zhuǎn)載自:
DevExpress技術(shù)交流群6:600715373 歡迎一起進群討論
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: