using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Design; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web.Caching; using System.Windows.Forms; using BrightIdeasSoftware; using GeoSigmaDrawLib; using SigmaDrawerElement; using UCDraw; using UCDraw.Editor; namespace SymbolLibManager { public partial class frmMarkEditor : DialogUIEditorFrom { private MarkLibrary _library = new MarkLibrary(); private List miList = null; private string symbolFile = string.Empty; private GeoSigmaXY geoFile = null; private GeoSigmaXY geoCurrent = null; private IntPtr doc = IntPtr.Zero; private IntPtr docSymbol = IntPtr.Zero; private RangeGetter drawerRangeGetter; private string markName = string.Empty; private bool createFlag = false; private string path = string.Empty; private bool isSearch = false; private new ListViewItem[] myCache; private int firstItem = 0; private List symbolItem = null; private IntPtr symbolOriginal = IntPtr.Zero; private string symbolFileName; private string currentNode = string.Empty; private string currentFilePath = string.Empty; private Dictionary nodeIsParent = null; // 记录前一项从缓存中删除,避免符号列表显示的图标错误 private string prevSymbolInList = string.Empty; private Drawer mainDrawer = null; private string symbolFileDir = string.Empty; private string symbolName = string.Empty; private int copyCount = 0; private string[] arrPath; private string[] arrPathBak; private string fileName = string.Empty; private int lvIndex = 0; private string lvText = string.Empty; private List currentMarks; public GeoSigmaXY GeoCurrent { get { return this.geoCurrent; } set { this.geoCurrent = value; } } public Drawer MainDrawer { get { return this.mainDrawer; } set { this.mainDrawer = value; } } public string CurrentFilePath { get { return currentFilePath; } set { currentFilePath = value; } } public RangeGetter DrawerRangeGetter { get { return drawerRangeGetter; } set { drawerRangeGetter = value; } } public frmMarkEditor() { InitializeComponent(); lvSymbol.View = View.LargeIcon; lvSymbol.VirtualMode = true; lvSymbol.VirtualListSize = 500; lvSymbol.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(lvSymbol_RetrieveVirtualItem); lvSymbol.CacheVirtualItems += new CacheVirtualItemsEventHandler(lvSymbol_CacheVirtualItems); tsTool.Renderer = MyToolStripRenderer.Instance; this.viewer.Geo = new GeoSigmaXY(); drawerRangeGetter = new RangeGetter(this.viewer.Drawer); this.viewer.Drawer.DrawerZoomIn += this.viewer.HRuler.Zoom; this.viewer.Drawer.DrawerZoomOut += this.viewer.HRuler.Zoom; this.viewer.Drawer.DrawerZoomIn += this.viewer.VRuler.Zoom; this.viewer.Drawer.DrawerZoomOut += this.viewer.VRuler.Zoom; this.viewer.Drawer.ShowAttrInfoChanged += GetElementInfo; this.viewer.Drawer.SymbolViewFlag = true; this.layerTree.LayerActiveEvent += GetLayer; var config = new Config(); config.WriteString("Display", "ZoomMode", "1"); foreach (var item in this.layerTree.Controls) { Control control = (Control)item; if (control.Name == "toolStrip1") { ToolStrip tsControl = (ToolStrip)control; tsControl.Items[8].Visible = false; } } var symbolFilePath = Directory.GetParent(Application.StartupPath); symbolFileName = symbolFilePath.FullName; currentMarks = new List(); //geoSymbol = new GeoSigma(); //geoSymbol.SetHWND(this.Handle); } public void GetLayer(string layerName) { pnlProperty.LayerName = layerName; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); layerTree.ResetLayers(""); var pathList = new StringBuilder(65535); GeoSigmaXY.LoadSymbolTree(pathList); arrPath = pathList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); arrPathBak = pathList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); int index = 0; var treeNodeList = new List(); nodeIsParent = new Dictionary(); foreach (var item in arrPath) { var symbolNode = new SymbolTreeNode(); index = item.IndexOf("\\"); if (index > -1) { symbolNode.Name = item.Substring(0, index); //currIndex = item.IndexOf(item.Substring(0, index)); symbolNode.Path = item.Substring(0, index); treeNodeList.Add(symbolNode); nodeIsParent.Add(symbolNode, true); } else { symbolNode.Name = item; symbolNode.Path = item; if (!treeNodeList.Contains(symbolNode)) { treeNodeList.Add(symbolNode); nodeIsParent.Add(symbolNode, false); } } } treeNodeList = treeNodeList.GroupBy(p => p.Name).Select(g => g.First()).ToList(); treeNodeList.Reverse(); //treeSymbol.Nodes.AddRange(treeNodeList); var root = treeSymbol.Nodes.Add("符号文件夹"); var currentFileNode = new TreeNode(); currentFileNode.Text = "当前文档符号"; root.Nodes.Add(currentFileNode); LoadTreeNodes(root, treeNodeList); root.Expand(); } public void LoadTreeNodes(TreeNode parent, List treeNodeList) { var childNodes = new List(); foreach (var treeNode in treeNodeList) { var node = new TreeNode(); if (treeNode.Name == null) { return; } node.Text = treeNode.Name; node.ImageIndex = 0; parent.Nodes.Add(node); for (int i = 0; i < arrPath.Length; i++) { if (arrPath[i].IndexOf(node.Text) > -1) { var symbolNode = new SymbolTreeNode(); string[] part = arrPath[i].Split('\\'); if (part.Length >= 2) { symbolNode.Name = part[1]; if (arrPathBak[i].EndsWith(part[1])) { symbolNode.Path = arrPathBak[i]; } else { symbolNode.Path = part[0] + "\\" + part[1]; } } if (!childNodes.Exists(r => r.Name == symbolNode.Name)) { if (symbolNode.Name != null) { if (arrPath[i].IndexOf(node.Text + "\\") > -1) { childNodes.Add(symbolNode); } } } arrPath[i] = arrPath[i].Replace(node.Text + "\\", ""); } } LoadTreeNodes(node, childNodes); childNodes.Clear(); } } public string GetTreeNodes(string str) { if (str.IndexOf("\\") > -1) { string[] node = str.Split('\\'); if (node.Length > 0) { return node[0]; } } return str; } public bool IsParentNode(SymbolTreeNode node) { if (nodeIsParent.Keys.Contains(node)) { return nodeIsParent[node]; } return false; } public string GetParentPath(string selectedNode) { int arrLen = arrPathBak.Length; for (int i = 0; i < arrLen; i++) { if (arrPathBak[i].IndexOf("\\" + selectedNode) > -1 && arrPathBak[i].EndsWith("\\" + selectedNode)) { return arrPathBak[i]; } } return string.Empty; } public List GetChildren(SymbolTreeNode parent) { int len = parent.Name.Length - 1; var children = new List(); var pathList = new StringBuilder(65535); GeoSigmaXY.LoadSymbolTree(pathList); var arrPath = pathList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var item in arrPath) { int m = item.IndexOf(parent.Name + "\\"); int n = item.IndexOf(parent.Path); if (m > -1 && item.IndexOf(parent.Name) > -1) { var node = new SymbolTreeNode(); if (item.IndexOf("\\") > -1) { string[] pathElem = item.Split('\\'); if (m == 0) { if (pathElem.Length >= 2) { node.Name = pathElem[1]; node.Path = item; } } else if (pathElem.Length >= 3) { node.Name = pathElem[2]; node.Path = item; } } else { node.Name = item; node.Path = item; } if (!children.Contains(node)) { if (!children.Contains(node)) { children.Add(node); if (item.IndexOf(node + "\\") > -1) { if (!nodeIsParent.ContainsKey(node)) { nodeIsParent.Add(node, true); } } else { if (!nodeIsParent.ContainsKey(node)) { nodeIsParent.Add(node, false); } } } } } else if (m == -1 && n == 0) { return children; } } children = children.GroupBy(p => p.Name).Select(g => g.First()).ToList(); return children; } private void GetTreeData(string path, TreeListView node) { if (!Directory.Exists(path)) return; //目录下的文件、文件夹集合 string[] diArr = System.IO.Directory.GetDirectories(path, "*", System.IO.SearchOption.AllDirectories); string[] rootfileArr = System.IO.Directory.GetFiles(path); //文件夹递归 for (int i = 0; i < diArr.Length; i++) { //增加父节点 string fileName = Path.GetFileNameWithoutExtension(diArr[i]); } } private void btnOk_Click(object sender, EventArgs e) { //if (olvSymbol.SelectedObject is MarkItem mi) //{ // if (mi is LibraryMarkItem lmi && DrawViewer.Current?.GetGeoSigma() is GeoSigma gs) // { // gs.MarkCopyLibraryToDocument(lmi.Id); // } // this.Value = mi.Name; //} DialogResult = DialogResult.OK; } private void btnCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; this.Close(); } private void tsbtnSearch_Click(object sender, EventArgs e) { //lvSymbol.VirtualListSize = 0; //for (int j = myCache.Length - 1; j >= 0; j++) //{ // //myCache[j].Remove(); // //if (myCache[j] != null) // //{ // myCache[j].ListView.VirtualListSize = 0; // //} //} imgIndex = 0; isSearch = true; var text = tstbSearch.Text; if (text == string.Empty) { return; } _library = MarkLibrary.GetMarkLibrary(); _library.GenerateNodes(); //var roots = _library.GetRoots().ToList(); var list = new List(); //int imgIndex = 5000; foreach (var node in _library.Nodes.OfType()) { var tmp = node.Marks.Where(r => r.Name.Contains(text)).ToList(); foreach (var item in tmp) { item.Image = item.Image; item.SymbolFilePath = node.Path; item.Index = item.Index; } var uniqueName = tmp.Distinct(); if (geoFile == null) { return; } geoFile.RemoveSymbolLibXy(); if (node is MarkLibraryNode lnode) { if (uniqueName.Count() > 0) { MarkLibrary.GenerateLibraryImage(uniqueName, symbolFileDir); } } list.AddRange(uniqueName); } // 搜索符号结果列表 var imglist = new ImageList(); lvSymbol.View = View.LargeIcon; lvSymbol.LargeImageList = imgSymbol; foreach (var item in list) { imgSymbol.Images.Add(item.Name, item.Image); } int i = 0; lvSymbol.Items.Clear(); ////lvSymbol.VirtualMode = true; //lvSymbol.VirtualListSize = 0; foreach (var item in list) { lvSymbol.VirtualListSize = list.Count; //lvSymbol.Items.Add(item.Name); //lvSymbol.Items[i].ImageIndex = 122;//item.Index//========================== lvSymbol.Items[i].Text = item.Name; lvSymbol.Items[i].Tag = item.SymbolFilePath; i++; } //foreach (var item in list) //{ // lvSymbol.Items.Add(item.Name); // lvSymbol.Items[i].ImageIndex = item.Index; // //lvSymbol.Items[i].ImageIndex = i; // lvSymbol.Items[i].Tag = item.SymbolFilePath; // i++; //} } public MarkLibraryNode GetMarkNode(string path) { var item = new MarkLibraryNode(); item.Path = path; var idList = new StringBuilder(65535); var nameList = new StringBuilder(65535); if (GeoSigmaXY.MarkLibraryLoopMark(path, idList, nameList)) { var arrId = idList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var arrName = nameList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); if (arrId.Length == arrName.Length) { for (int i = 0; i < arrId.Length; i++) { item.Marks.Add(new DocumentMarkItem() { Name = arrName[i], Id = arrId[i], Index = i //0904 }); } } } return item; } private void GetElementInfo(DrawerElementProperty elementData) { DrawerElementProperty property = elementData; pnlProperty.Viewer = this.viewer; pnlProperty.ShowElementProperty(property); } private void btnZoomIn_Click(object sender, EventArgs e) { this.ToolZoomIn(); } private void btnZoomOut_Click(object sender, EventArgs e) { this.ToolZoomOut(); } private void tsbPan_Click(object sender, EventArgs e) { this.ToolViewPan(); } private void tsbViewWindow_Click(object sender, EventArgs e) { this.ToolViewWindow(); } private void tsbViewAll_Click(object sender, EventArgs e) { this.ViewAll(); } private void tsbRedraw_Click(object sender, EventArgs e) { this.Redraw(); } private void undoButton_Click(object sender, EventArgs e) { this.viewer.Drawer.Undo(); this.viewer.Drawer.ReDraw(); } private void redoButton_Click(object sender, EventArgs e) { this.viewer.Drawer.Redo(); this.viewer.Drawer.ReDraw(); } private void tsbToolDefault_Click(object sender, EventArgs e) { this.ToolDefault(); this.tsbSelect.Checked = false; this.CancelDrawHandle(); } private void tsbSelect_Click(object sender, EventArgs e) { this.ToolSelect(); this.tsbToolDefault.Checked = false; this.CancelDrawHandle(); } private void CancelDrawHandle() { this.tsbCurveAdd.Checked = false; this.drawRectangleButton.Checked = false; this.drawEllipseButton.Checked = false; this.drawTextButton.Checked = false; } private void CancelMouseShape() { this.tsbToolDefault.Checked = false; this.tsbSelect.Checked = false; } private void tsbCurveAdd_Click(object sender, EventArgs e) { this.ToolAddCurve(); this.drawRectangleButton.Checked = false; this.drawEllipseButton.Checked = false; this.drawTextButton.Checked = false; this.tsbCircle.Checked = false;//----------- this.CancelMouseShape(); } private void drawRectangleButton_Click(object sender, EventArgs e) { this.ToolRectangle(); this.tsbCircle.Checked = false; this.tsbCurveAdd.Checked = false; this.drawEllipseButton.Checked = false; this.drawTextButton.Checked = false; this.CancelMouseShape(); } private void drawEllipseButton_Click(object sender, EventArgs e) { this.ToolEllipse(); this.tsbCircle.Checked = false; this.tsbCurveAdd.Checked = false; this.drawRectangleButton.Checked = false; this.drawTextButton.Checked = false; this.CancelMouseShape(); } private void drawTextButton_Click(object sender, EventArgs e) { this.ToolText(); this.tsbCurveAdd.Checked = false; this.drawRectangleButton.Checked = false; this.drawEllipseButton.Checked = false; this.CancelMouseShape(); } /// /// 画线工具 /// public void ToolAddCurve() { this.viewer.ActiveTool = DrawToolType.Curve;//??????? //this.viewer.Drawer.ActiveTool = DrawToolType.Curve; } /// /// 放大工具 /// public void ToolZoomIn() { this.viewer.ZoomIn(); } /// /// 缩小 /// public void ToolZoomOut() { if (this.viewer.HRuler.Ruler.ScalLen < 0.52) { this.viewer.Drawer.ZoomOut(); } } /// /// 移动 /// public void ToolViewPan() { tsbPan.Checked = !tsbPan.Checked; if (tsbPan.Checked == true) { this.viewer.Drawer.SetViewOperationKind(ViewOperationKind.ViewPan); } else { this.viewer.Drawer.SetViewOperationKind(ViewOperationKind.Invalid); } tsbViewWindow.Checked = false; //去掉窗口缩放按钮的选中图标 } /// /// 窗口放大 /// public void ToolViewWindow() { tsbViewWindow.Checked = !tsbViewWindow.Checked; if (tsbViewWindow.Checked == true) { viewer.SetViewOperationKind(ViewOperationKind.ViewWindow); } else { viewer.SetViewOperationKind(ViewOperationKind.Invalid); } this.tsbPan.Checked = false; //去掉平移按钮的选中状态 } public void ViewAll() { this.viewer.Drawer.ViewAll(); } public void Redraw() { this.viewer.Drawer.ReDraw(); } /// /// 默认状态 /// public void ToolDefault() { this.viewer.ActiveTool = DrawToolType.Default; } /// /// 选择工具 /// public void ToolSelect() { this.viewer.ActiveTool = DrawToolType.Select; } /// /// 矩形绘制工具 /// public void ToolRectangle() { this.viewer.ActiveTool = DrawToolType.Rectangle; } /// /// 椭圆工具 /// public void ToolEllipse() { this.viewer.ActiveTool = DrawToolType.Ellipse; } /// /// 文本绘制工具 /// public void ToolText() { this.viewer.ActiveTool = DrawToolType.Text; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (geoFile == null) { this.viewer.Drawer.Geo = new GeoSigmaXY(); InitRuler(); } else { this.viewer.Drawer.Geo = geoFile; } Graphics g = e.Graphics; Rectangle canvasRect = ClientRectangle; canvasRect.Width -= Height; //即减去offset canvasRect.Width -= Height; //即减去offset } protected void InitRuler() { //this.viewer.HRuler.Init(this.viewer.Drawer.GetRangeGetter()); //this.viewer.VRuler.Init(this.viewer.Drawer.GetRangeGetter()); this.viewer.Drawer.MouseMove += this.viewer.HRuler.ProcessMouseMove; this.viewer.Drawer.DrawerZoomIn += this.viewer.HRuler.Zoom; this.viewer.Drawer.DrawerZoomOut += this.viewer.HRuler.Zoom; this.viewer.Drawer.DrawerViewAll += this.viewer.HRuler.Zoom; this.viewer.Drawer.DrawerViewPan += this.viewer.HRuler.ReDraw; this.viewer.Drawer.DrawerOnPaint += this.viewer.HRuler.ReDraw; viewer.Drawer.MouseMove += this.viewer.VRuler.ProcessMouseMove; viewer.Drawer.DrawerZoomIn += this.viewer.VRuler.Zoom; viewer.Drawer.DrawerZoomOut += this.viewer.VRuler.Zoom; viewer.Drawer.DrawerViewAll += this.viewer.VRuler.Zoom; viewer.Drawer.DrawerViewPan += this.viewer.VRuler.ReDraw; viewer.Drawer.DrawerOnPaint += this.viewer.VRuler.ReDraw; } private void frmMarkEditor_Load(object sender, EventArgs e) { } private void tsbCircle_Click(object sender, EventArgs e) { this.tsbCircle.Checked = !this.tsbCircle.Checked; this.drawRectangleButton.Checked = false; this.drawEllipseButton.Checked = false; this.tsbCurveAdd.Checked = false; if (this.currentNode == "当前文档符号") { GeoCurrent.SetDocData(docSymbol); geoCurrent.DrawCircleCurrent(); } else { geoFile.SetDocData(docSymbol); geoFile.DrawCircleSymbol(); } this.viewer.Drawer.ReDraw(); } private void tsbNew_Click(object sender, EventArgs e) { if (this.currentNode == "当前文档符号") { this.CreateNewSymbol(geoCurrent, sender, e); //geoCurrent.DocBak(); } else { this.CreateNewSymbol(geoFile, sender, e); } } public void CreateNewSymbol(GeoSigmaXY geo, object sender, EventArgs e) { bool modifyFlag = false; DialogResult resultInfo = DialogResult.Abort; if (geo != null) { modifyFlag = geo.Sigma_IsDocumentModified(); } if (modifyFlag) { resultInfo = MessageBox.Show("是否保存当前修改", "提示", MessageBoxButtons.YesNo); if (resultInfo == DialogResult.Yes) { //执行保存 this.tsbSave_Click(sender, e); //修改后删除缓存中的符号 CacheHelper.Remove(prevSymbolInList); modifyFlag = false; } else { if (resultInfo != DialogResult.OK) { geo.SetDocData(doc); geo.ReplaceSymbol(markName, symbolOriginal); } } } if (miList == null) { return; } int result = 0; createFlag = true; //string symbolName = string.Empty; string itemName = string.Empty; int max = 0; foreach (var item in miList) { itemName = item.Name; if (itemName.IndexOf("新建符号") > -1) { itemName = itemName.Substring(4); //int itemNum = int.Parse(itemName); if (!int.TryParse(itemName, out result)) { return; } int itemNum = result; if (itemNum >= max) { max = itemNum; } } } max++; symbolName = "新建符号" + max; var mi = new LibraryMarkItem(); mi.Name = symbolName; mi.Id = symbolName; var mdNode = new MarkLibraryNode(); mdNode.Marks.Add(mi); MarkLibrary.GenerateLibraryImage(mdNode.Marks, symbolFileDir); miList.Add(mi); int cx = 30, cy = 30; var img = new Bitmap(cx, cy); //olvSymbol.Objects = miList; var imglist = new ImageList(); //var symbolItemSet = new List(); //var symbolItem = new ListViewItem(mi.Name); //symbolItemSet.Add(symbolItem); lvSymbol.VirtualListSize = miList.Count; //lvSymbol.Items.Add(mi.Name); lvSymbol.Items[miList.Count - 1].Text = symbolName; lvSymbol.Items[miList.Count - 1].ImageIndex = -1; if (mi.Image == null) { imglist.Images.Add(img); } else { imglist.Images.Add(mi.Image); } lvSymbol.SmallImageList = imglist; Graphics g = Graphics.FromImage(img); if (GeoSigmaXY.MarkLibraryNewSymbol(mi.Name, g.GetHdc(), cx, cy)) { //加上这句才能回写到bitmap中 g.ReleaseHdc(); mi.Image = img; } if (symbolFile != string.Empty) { geo.SetDocData(doc); //geo.DeleteRectangleRange(doc); geo.DeleteRectangleRange(); ////if (resultInfo != DialogResult.OK) ////{ //// geo.ReplaceSymbol(markName,symbolOriginal); ////} geo.CreateNewSymbol(symbolName); var flag = geo.SaveDocument(symbolFile); if (!flag) { MessageBox.Show("创建失败"); } } createFlag = false; this.GetSymbolCursorLocation(); } private void tsbSave_Click(object sender, EventArgs e) { if (this.currentNode == "当前文档符号") { if (currentFilePath != string.Empty) { geoCurrent.DeleteRectangleRange(); geoCurrent.CurrDocEditSymbol(doc, markName); geoFile.CurrentSymbolWindowShow(); this.mainDrawer.ReDraw(); var flag = geoCurrent.SaveDocument(currentFilePath); //geoCurrent.SetDocData(currDoc);//---------------- //this.mainDrawer.ReDraw(); if (flag) { CacheHelper.Remove(prevSymbolInList); //geoCurrent.DocBak(); MessageBox.Show("编辑已保存"); } } } else { if (symbolFile != string.Empty) { if (symbolFile != string.Empty) { //geoFile.DeleteRectangleRange(); geoFile.DeleteRectFrameSymbol(docSymbol); geoFile.SetDocData(doc); //var flag = geoFile.SaveDocument(symbolFile); var flag = geoFile.SaveFile(); if (flag) { CacheHelper.Remove(prevSymbolInList); //geoFile.SymbolDocView(docSymbol, markName); geoFile.SetDocData(docSymbol); geoFile.RectangleRange(); MessageBox.Show("编辑已保存"); } } } } } private void tsbDelete_Click(object sender, EventArgs e) { string symbolName = string.Empty; if (lvSymbol.SelectedIndices != null && lvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection c = lvSymbol.SelectedIndices; symbolName = lvSymbol.Items[c[0]].Text; } foreach (var item in miList) { if (item.Name == symbolName) { miList.Remove(item); break; } } geoFile.SetDocData(doc); geoFile.DeleteSymbol(symbolName); var flag = geoFile.SaveDocument(symbolFile); if (!flag) { MessageBox.Show("删除失败"); } int i = 0; lvSymbol.VirtualListSize = miList.Count; foreach (var item in miList) { lvSymbol.Items[i].Text = item.Name; lvSymbol.Items[i].ImageIndex = item.Index; lvSymbol.Items[i].Tag = item.SymbolFilePath; i++; } } private void lvSymbol_SelectedIndexChanged(object sender, EventArgs e) { if (this.currentNode == "当前文档符号") { ShowSymbol(geoCurrent, "", sender, e); } else { ShowSymbol(geoFile, "symbolFile", sender, e); } //this.tsbViewAll_Click(sender, e); } public void ShowSymbol(GeoSigmaXY geo, string flag, object sender, EventArgs e) { string currSymbol = string.Empty; if (lvSymbol.SelectedIndices != null && lvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection c = lvSymbol.SelectedIndices; currSymbol = lvSymbol.Items[c[0]].Text; lvIndex = c[0]; lvText = currSymbol; } if (geo == null) { return; } if (currSymbol != string.Empty) { //doc = geo.GetDocData(); geo.SetDocData(doc); symbolOriginal = geo.SaveSymbolOriginal(currSymbol); } bool modifyFlag = false; modifyFlag = geo.Sigma_IsDocumentModified(); if (modifyFlag && flag == "symbolFile") { DialogResult result = MessageBox.Show("是否保存当前修改", "提示", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { //执行保存 this.tsbSave_Click(sender, e); //修改后删除缓存中的符号 CacheHelper.Remove(prevSymbolInList); modifyFlag = false; } } if (!createFlag) { var symbol = lvSymbol.SelectedIndices; if (symbol != null) { if (lvSymbol.SelectedIndices != null && lvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection c = lvSymbol.SelectedIndices; var symbolName = lvSymbol.Items[c[0]].Text; if (symbolName != string.Empty) { markName = symbolName; } prevSymbolInList = symbolFileDir + "\\" + markName; } string pathName = string.Empty; if (lvSymbol.SelectedIndices != null && lvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection cn = lvSymbol.SelectedIndices; if (lvSymbol.Items[cn[0]].Tag == null) { this.lbSymbolNodePath.Text = this.currentNode; pathName = fileName; } else { pathName = lvSymbol.Items[cn[0]].Tag.ToString(); this.lbSymbolNodePath.Text = pathName; } path = string.Empty; string parentPath = GetParentPath(fileName); string partPath = string.Empty; if (flag == "symbolFile") { if (isSearch) { symbolFile = symbolFileName + "\\Mark" + "\\" + pathName + ".dfd"; } else { if (parentPath != string.Empty) { symbolFile = symbolFileName + "\\Mark\\" + parentPath + ".dfd"; } else { symbolFile = symbolFileName + "\\Mark\\" + fileName + ".dfd"; } } if (!File.Exists(symbolFile)) return; geoFile = this.viewer.Drawer.OpenFile(symbolFile); doc = geoFile.GetDocData(); geoFile.SetMarkDataSymbol(markName); } else { symbolFile = currentFilePath; if (!File.Exists(symbolFile)) return; if (geoFile == null) { geoFile = new GeoSigmaXY(); //doc = geoFile.GetDocData(); } if (geoFile != null) { geoCurrent.GetDocData(); geoCurrent.DocBak(markName); geoFile.SetMark2Data(markName); } } //为符号编辑属性设置添加 this.viewer.Geo = geoFile; //doc = geoFile.GetDocData(); //geoFile.SetMark2Data(markName); docSymbol = geoFile.GetDocData(); if (!createFlag) { if (this.currentNode == "当前文档符号") { geoFile.RectangleRange(); } else { geoFile.RectangleRangeSymbol(); } geoFile.SetLayerState("RectRangeBackground", LayerStatus.VIEW_NOT_EDIT); } this.viewer.Drawer.Geo = geoFile; } this.viewer.Drawer.ReDraw(); } } if (geoFile != null) { string strLayers = geoFile.GetLayers(); string strReplace = string.Empty; if (!string.IsNullOrEmpty(strLayers)) { if (strLayers.IndexOf("Layer:\\RectRangeBackground") > 0) { strReplace = strLayers.Replace("Layer:\\RectRangeBackground", ""); } //string CurrentLayer = viewer.GetCurrentLayer(); string CurrentLayer = geoFile.GetCurrentLayer(); pnlProperty.Viewer = this.viewer; //layerTree.SymbolFlag = true; layerTree.DrawViewer = this.viewer; if (strReplace != string.Empty) { string layers = string.Empty; string[] saFullLayers = Regex.Split(strReplace, "\r\n"); for (int i = 0; i < saFullLayers.Length; i++) { if (saFullLayers[i] != "") { layers += "10|" + saFullLayers[i] + "\r\n"; } } layerTree.ResetLayers(layers); } layerTree.SetCurrentLayer(CurrentLayer); this.viewer.Drawer.ActiveTool = DrawToolType.Default; this.tsbSelect.Checked = false; } } this.ToolSelect(); this.tsbSelect.Checked = true; } private void tsmiRename_Click(object sender, EventArgs e) { ListView.SelectedIndexCollection c = lvSymbol.SelectedIndices; lvSymbol.LabelEdit = true; if (c.Count > 0) { lvSymbol.Items[c[0]].BeginEdit(); } } private void lvSymbol_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { ContextMenuStrip = this.cmsSymbolMenu; } } private void lvSymbol_AfterLabelEdit(object sender, LabelEditEventArgs e) { var symbolName = e.Label; if (symbolName == string.Empty || symbolName == null) { MessageBox.Show("此名称不能为空!"); e.CancelEdit = true; return; } //SymbolTreeNode fileName = (SymbolTreeNode)treeSymbol.SelectedObject; geoFile = this.viewer.Drawer.OpenFile(symbolFile); doc = geoFile.GetDocData(); geoFile.RemoveSymbolLibXy(); var ml = new MarkLibrary(); string parentPath = GetParentPath(fileName); var lnode = new MarkLibraryNode(); if (parentPath == string.Empty) { lnode = ml.GetCurrentSelectSymbolFile(fileName); } else { lnode = ml.GetCurrentSelectSymbolFile(parentPath); } miList = lnode.Marks; if (geoFile != null) { //geoFile.DeleteRectangleRange(doc); geoFile.DeleteRectangleRange(); geoFile.SetDocData(doc); foreach (var item in miList) { if (symbolName != null) { if (item.Name == symbolName.Trim()) { MessageBox.Show("此名称已存在!"); e.CancelEdit = true; return; } } } geoFile.SymbolRename(markName, symbolName); markName = symbolName; var flag = geoFile.SaveDocument(symbolFile); if (!flag) { MessageBox.Show("重命名失败"); } } } private void tsmiCopy_Click(object sender, EventArgs e) { string symboleName = string.Empty; string itemName = string.Empty; string copyName = string.Empty; if (lvSymbol.SelectedIndices != null && lvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection c = lvSymbol.SelectedIndices; symboleName = lvSymbol.Items[c[0]].Text; } else { return; } copyName = symboleName + "副本"; int max = 0; int symboleNameLen = 0; int result = 0; int index = 0; foreach (var item in miList) { itemName = item.Name; if (symboleName == itemName) { index = item.Index; } if (itemName.IndexOf(copyName) == 0) { symboleNameLen = copyName.Length; itemName = itemName.Substring(symboleNameLen); if (!int.TryParse(itemName, out result)) { return; } //int itemNum = int.Parse(itemName); int itemNum = result; if (itemNum >= max) { max = itemNum; } } } max++; var mi = new LibraryMarkItem(); mi.Name = copyName + max; mi.Id = copyName + max; mi.Index = index; var mdNode = new MarkLibraryNode(); mdNode.Marks.Add(mi); miList.Add(mi); int cx = 30, cy = 30; int len = 0; var img = new Bitmap(cx, cy); var imglist = new ImageList(); if (geoFile != null) { geoFile.SetDocData(doc); geoFile.CopySymbol(symboleName, mi.Name); //geoFile.DeleteRectangleRange(doc); geoFile.DeleteRectangleRange(); var flag = geoFile.SaveDocument(symbolFile); geoFile.RemoveSymbolLibXy(); MarkLibrary.GenerateLibraryImage(mdNode.Marks, symbolFileDir); lvSymbol.View = View.LargeIcon; lvSymbol.LargeImageList = imgSymbol; int i = 0; len = miList.Count + 1; lvSymbol.VirtualListSize = len; foreach (var item in mdNode.Marks) { lvSymbol.Items[len - 1].Text = item.Name; lvSymbol.Items[len - 1].ImageIndex = item.Index; i++; } lvSymbol.VirtualListSize = miList.Count; int m = 0; foreach (var item in miList) { lvSymbol.Items[m].Text = item.Name; lvSymbol.Items[m].ImageIndex = item.Index; lvSymbol.Items[m].Tag = item.SymbolFilePath; m++; } if (!flag) { MessageBox.Show("符号复制失败"); } //geoFile.DocBak(); copyCount++; } if (lvSymbol.Items.Count > 0) { lvSymbol.Focus(); lvSymbol.Items[lvSymbol.Items.Count - 1].Selected = true; } this.GetSymbolCursorLocation(); } private void GetSymbolCursorLocation() { if (lvSymbol.SelectedIndices != null && lvSymbol.SelectedIndices.Count > 0) { ListView.SelectedIndexCollection c = lvSymbol.SelectedIndices; lvSymbol.Focus(); //lvSymbol.Items[c[0]].Selected = false; lvSymbol.Items[lvIndex].Selected = false; lvSymbol.Items[lvSymbol.Items.Count - 1].Selected = true; lvSymbol.EnsureVisible(lvSymbol.Items.Count - 1); } } private void gridBtn_Click(object sender, EventArgs e) { viewer.SwitchGrid(); this.viewer.Geo.SetGridStep(0.1, 0.1); } private void highLightTipBtn_Click(object sender, EventArgs e) { viewer.ActiveTool = DrawToolType.HighLightTip; } private int imgIndex = 0; private void lvSymbol_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { if (myCache != null && e.ItemIndex >= firstItem && e.ItemIndex < firstItem + myCache.Length) { e.Item = myCache[e.ItemIndex - firstItem]; //e.Item.ImageIndex = imgIndex; //imgIndex++; } else { //e.Item = new ListViewItem(symbolName); e.Item = new ListViewItem(e.ItemIndex.ToString()); } } private void lvSymbol_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) { if (myCache != null && e.StartIndex >= firstItem && e.EndIndex <= firstItem + myCache.Length) { //for (int i = 0; i < myCache.Length; i++) //{ // if (myCache[i] != null) // { // myCache[i].ListView.VirtualListSize = 0; // } //} return; } firstItem = e.StartIndex; int length = e.EndIndex - e.StartIndex + 1; myCache = new ListViewItem[length]; int x = 0; for (int i = e.StartIndex; i <= e.EndIndex; i++) { if (symbolItem != null) { //// 加判断如果是复制 //ListViewItem item = new ListViewItem(symbolItem[i].Name); //if (symbolItem[i].Name.IndexOf("新建符号") > -1) //{ // item.ImageIndex = -1; //} //else //{ // item.ImageIndex = i; //} //myCache[x] = item; if (i < symbolItem.Count) { // 加判断如果是复制 ListViewItem item = new ListViewItem(symbolItem[i].Name); if (symbolItem[i].Name.IndexOf("新建符号") > -1) { item.ImageIndex = -1; } else { item.ImageIndex = i; } myCache[x] = item; } } else { ListViewItem item = new ListViewItem(string.Empty); item.ImageIndex = i; //item.Text = "009"; myCache[x] = item; //break; } x++; } } private void treeSymbol_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) //async { imgIndex = 0; TreeView Tv_temp = (TreeView)sender; if ((sender as TreeView) != null) { // 点击树节点防止上次选中的节点高亮显示闪一下 Tv_temp.SelectedNode = Tv_temp.GetNodeAt(e.X, e.Y); } if (e.Button == MouseButtons.Left) { lvSymbol.Items.Clear(); imgSymbol.Images.Clear(); lvSymbol.VirtualListSize = 0; TreeNode tn = this.treeSymbol.GetNodeAt(e.Location); currentNode = tn.Text; if (tn != null && tn.Bounds.Contains(e.Location)) { if (tn.Nodes.Count == 0) { if (tn.Text == "当前文档符号") { if (this.geoCurrent != null) { symbolFile = currentFilePath; if (currentMarks.Count == 0) { //geoCurrent.SetDocData(doc); currentMarks = MarkLibrary.GetDocumentMarks(this.geoCurrent); } int i = 0; //lvSymbol.Items.Clear(); //imgSymbol.Images.Clear(); this.lvSymbol.BeginUpdate(); lvSymbol.VirtualListSize = currentMarks.Count; lvSymbol.View = View.LargeIcon; foreach (var item in currentMarks) { if (item.Image == null) { MarkLibrary.GenerateDocumentImage(new[] { item }, geoCurrent); } if (item.Image != null) { imgSymbol.Images.Add(item.Name, item.Image); } lvSymbol.Items[i].Text = item.Name; lvSymbol.Items[i].ImageIndex = item.Index;//????? i++; } lvSymbol.LargeImageList = imgSymbol; this.lvSymbol.EndUpdate(); doc = geoCurrent.GetDocData(); miList = currentMarks; } } else { isSearch = false; var pathList = new StringBuilder(65535); GeoSigmaXY.LoadSymbolTree(pathList); var arrPath = pathList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); fileName = e.Node.Text; path = string.Empty; string parentPath = GetParentPath(fileName); if (parentPath != string.Empty) { symbolFile = symbolFileName + "\\Mark\\" + parentPath + ".dfd"; } else { symbolFile = symbolFileName + "\\Mark\\" + fileName + ".dfd"; } var lnode = new MarkLibraryNode(); if (parentPath != string.Empty) { lnode = GetMarkNode(parentPath); } else { lnode = GetMarkNode(fileName); } geoFile = this.viewer.Drawer.OpenFile(symbolFile); if (geoFile == null) { return; } doc = geoFile.GetDocData(); geoFile.RemoveSymbolLibXy(); //await Task.Run(() => //{ if (parentPath != string.Empty) { MarkLibrary.GenerateLibraryImage(lnode.Marks, parentPath); } else { MarkLibrary.GenerateLibraryImage(lnode.Marks, fileName); } //}); miList = lnode.Marks; symbolItem = lnode.Marks; lvSymbol.View = View.LargeIcon; lvSymbol.LargeImageList = imgSymbol; int i = 0; this.lvSymbol.BeginUpdate(); lvSymbol.VirtualListSize = lnode.Marks.Count; foreach (var item in lnode.Marks) { if (item.Image != null) { imgSymbol.Images.Add(item.Name, item.Image); } lvSymbol.Items[i].Text = item.Name; lvSymbol.Items[i].ImageIndex = item.Index; i++; } lvSymbol.EndUpdate(); } var geoBlank = new GeoSigmaXY(); geoBlank.RectangleRange(); //geoBlank.SetLayerState("Layer:\\RectRangeBackground", LayerStatus.VIEW_NOT_EDIT); geoBlank.SetLayerState("RectRangeBackground", LayerStatus.VIEW_EDIT); this.viewer.Drawer.Geo = geoBlank; this.viewer.Drawer.ReDraw(); if (lvSymbol.Items.Count > 0) { lvSymbol.Focus(); if (this.currentNode != "当前文档符号") { lvSymbol.Items[0].Selected = true; } lvSymbol_SelectedIndexChanged(sender, e); } this.ToolSelect(); this.tsbSelect.Checked = true; } } } } } public class MarkEditor : DialogUIEditor { private List _items = new List(); public override bool GetPaintValueSupported(ITypeDescriptorContext context) { return true; } public override void PaintValue(PaintValueEventArgs e) { if (e.Value is string s) { MarkItem mi = _items.FirstOrDefault(r => r.Name == s); if (mi == null) { // foreach (var dm in MarkLibrary.GetDocumentMarks()) // { // var tmp = _items.FirstOrDefault(r => r.Id == dm.Id); // if (tmp == null) // { // _items.Add(dm); // } // else // { // tmp.Name = dm.Name; // tmp.Image = dm.Image; // } // } // mi = _items.FirstOrDefault(r => r.Name == s); } if (mi != null) { if (mi.Image == null) MarkLibrary.GenerateDocumentImage(new[] { mi }, null); e.Graphics.DrawImage(mi.Image, e.Bounds); } } base.PaintValue(e); } } #region 符号 public class MarkItem { public string Name { get; set; } public string Id { get; set; } public Image Image { get; set; } public int Index { get; set; } public IntPtr PXy { get; set; } public string SymbolFilePath { get; set; } } public class DocumentMarkItem : MarkItem { } public class LibraryMarkItem : MarkItem { } public abstract class MarkBaseNode { private string _path; private string name; public string Path { get => _path;//string.Join("\\", PathEx); set { _path = value; PathEx.Clear(); PathEx.AddRange(value.Split(new[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)); } } public List PathEx { get; set; } = new List(); public string Name { get { if (PathEx.Count > 0) return PathEx.Last(); //return string.Empty; return name; } set { name = value; } } public int Level => PathEx.Count; public string GetPathByLevel(int level) { return string.Join("\\", PathEx.Take(level)); } public bool IsParentOf(MarkBaseNode rhs) { if (this.PathEx.Count == rhs.PathEx.Count - 1) { int count = 0; for (int i = 0; i < this.PathEx.Count; i++) { if (this.PathEx[i] == rhs.PathEx[i]) count++; } return count == this.PathEx.Count; } return false; } public bool IsChildOf(MarkBaseNode rhs) { return rhs.IsParentOf(this); } public bool IsAncestorOf(MarkBaseNode rhs) { if (this.PathEx.Count < rhs.PathEx.Count) { int count = 0; for (int i = 0; i < this.PathEx.Count; i++) { if (this.PathEx[i] == rhs.PathEx[i]) count++; } return count == this.PathEx.Count; } return false; } public bool IsPosterityOf(MarkBaseNode rhs) { return rhs.IsAncestorOf(this); } } public class MarkVirtualNode : MarkBaseNode { } public class MarkItemNode : MarkBaseNode { public List Marks { get; set; } = new List(); public override string ToString() { return $"{Path}: {Marks.Count}"; } } public class MarkLibraryNode : MarkItemNode { } public class MarkDocumentNode : MarkItemNode { } public class MarkLibrary { private static int imgIndex = 0; public List Items { get; set; } = new List(); public bool Empty => Items.Count == 0; public List Nodes { get; set; } = new List(); public void GenerateNodes() { List GetRoots() { var list = new List(); list.AddRange(this.Items.OfType()); var parents = this.Items.Where(r => !(r is MarkDocumentNode)) .Where(r => !this.Items.Any(k => k.IsParentOf(r))); list.AddRange(parents.Where(r => r.PathEx.Count != 1) .Select(r => r.PathEx[0]) .Distinct() .Select(r => new MarkVirtualNode() { Path = r }) ); list.AddRange(parents.Where(r => r.PathEx.Count == 1)); return list; } List GetChildren(MarkBaseNode node) { var list = new List(); var tmp = this.Items.Where(r => r.IsPosterityOf(node)); list.AddRange(tmp.Where(r => !r.IsChildOf(node)) .Select(r => r.GetPathByLevel(node.Level + 1)) .Distinct() .Select(r => new MarkVirtualNode() { Path = r }) .ToList() ); list.AddRange(tmp.Where(r => r.IsChildOf(node)).ToList()); var children = list.SelectMany(r => GetChildren(r)).ToList(); list.AddRange(children); return list; } Nodes.Clear(); var roots = GetRoots(); Nodes.AddRange(roots); var nodes = roots.SelectMany(r => GetChildren(r)); Nodes.AddRange(nodes); } public IEnumerable GetRoots() { var list = new List(); list.AddRange(Nodes.OfType()); list.AddRange(Nodes.OfType().Where(r => r.Level == 1)); list.AddRange(Nodes.OfType().Where(r => r.Level == 1)); return list; } public IEnumerable GetChildren(MarkBaseNode parent) { foreach (var mln in Nodes) { if (mln.IsChildOf(parent)) yield return mln; } } public MarkBaseNode GetParent(MarkBaseNode child) { foreach (var mln in Nodes) { if (mln.IsParentOf(child)) return mln; } return null; } #region 接口 public static List GetDocumentMarks(GeoSigmaXY geo) { var list = new List(); var idList = new StringBuilder(65535); var nameList = new StringBuilder(65535); if (geo.MarkLoopName(idList, nameList)) { var arrId = idList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var arrName = nameList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); if (arrId.Length == arrName.Length) { for (int i = 0; i < arrId.Length; i++) { list.Add(new DocumentMarkItem() { Name = arrName[i], Id = arrId[i], Index = i }); } } } return list; } public static MarkLibrary GetMarkLibrary() { var library = new MarkLibrary(); //library.Items.Add(new MarkDocumentNode() //{ // Path = "当前文件符号", // Marks = GetDocumentMarks(), //}); library.Items.AddRange(GetDefaultLibrary().Items); return library; } private static MarkLibrary _defaultMarkLibrary = new MarkLibrary(); public static MarkLibrary GetDefaultLibrary() { int imgIndex = 0; if (_defaultMarkLibrary.Empty) { var pathList = new StringBuilder(65535); if (GeoSigmaXY.MarkLibraryLoopName(pathList)) { var arrPath = pathList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var path in arrPath) { var item = new MarkLibraryNode() { Path = path }; var idList = new StringBuilder(65535); var nameList = new StringBuilder(65535); if (GeoSigmaXY.MarkLibraryLoopMark(path, idList, nameList)) { var arrId = idList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var arrName = nameList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); if (arrId.Length == arrName.Length) { for (int i = 0; i < arrId.Length; i++) { item.Marks.Add(new DocumentMarkItem() { Name = arrName[i], Id = arrId[i], Index = imgIndex }); imgIndex++; } } } _defaultMarkLibrary.Items.Add(item); } } } return _defaultMarkLibrary; } public MarkLibraryNode GetCurrentSelectSymbolFile(string path) { var item = new MarkLibraryNode(); item.Path = path; var idList = new StringBuilder(65535); var nameList = new StringBuilder(65535); if (GeoSigmaXY.MarkLibraryLoopMark(path, idList, nameList)) { var arrId = idList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var arrName = nameList.ToString().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); if (arrId.Length == arrName.Length) { for (int i = 0; i < arrId.Length; i++) { item.Marks.Add(new DocumentMarkItem() { Name = arrName[i], Id = arrId[i], Index = i //0904 }); } } } return item; } public static void GenerateDocumentImage(IEnumerable marks, GeoSigmaXY geo) { //if (geo is GeoSigma gs) //{ foreach (var nm in marks) { int cx = 50, cy = 50; var img = new Bitmap(cx, cy); Graphics g = Graphics.FromImage(img); if (geo.MarkDrawByName(nm.Id, g.GetHdc(), cx, cy)) { //加上这句才能回写到bitmap中 g.ReleaseHdc(); nm.Image = img; //nm.Image.Save($"d:\\{nm.Name}.bmp"); } } //} } public static void GenerateLibraryImage(IEnumerable marks, string path) { foreach (var nm in marks) { string symbolKey = string.Empty; symbolKey = path + "\\" + nm.Name; if (CacheHelper.Exist(symbolKey)) { nm.Image = (Image)CacheHelper.GetValue(symbolKey); continue; } int cx = 30, cy = 30; var img = new Bitmap(cx, cy); Graphics g = Graphics.FromImage(img); if (GeoSigmaXY.MarkLibraryDrawByName(nm.Id, g.GetHdc(), cx, cy)) { if (!CacheHelper.Exist(symbolKey)) { CacheHelper.Add(symbolKey, img); } //加上这句才能回写到bitmap中 g.ReleaseHdc(); nm.Image = img; //nm.Image.Save($"d:\\{nm.Name}.bmp"); } } } #endregion } #endregion #region MarkItemRenderer internal class MarkItemRenderer : BrightIdeasSoftware.BaseRenderer { public override bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle r, object x) { var ret = base.RenderItem(e, g, r, x); if (x is MarkItem mi) { if (e.Item.Selected) { g.FillRectangle(Brushes.LightGray, r); } int cx = 30; int cy = 30; int size = Math.Min(r.Width - cx, r.Height - cy); var rcImageBorder = new Rectangle(r.Left + (r.Width - size) / 2, r.Top, size, size); rcImageBorder.Inflate(-1, -1); var rcImage = rcImageBorder; rcImage.Inflate(-2, -2); Rectangle rcDraw = new Rectangle(rcImage.Location, new Size(rcImage.Height, rcImage.Height)); g.DrawImage(mi.Image, rcDraw); g.DrawRectangle(Pens.Black, rcImageBorder); StringFormat fmt = new StringFormat(); fmt.LineAlignment = StringAlignment.Near; fmt.Alignment = StringAlignment.Center; g.DrawString(mi.Name, this.Font, Brushes.Black, new Rectangle(r.Left, r.Top + size, r.Width, r.Height - size) , fmt); return true; } return ret; } } #endregion public class SymbolTreeNode { private string name; private string path; private int index; public string Name { get { return name; } set { name = value; } } public string Path { get { return path; } set { path = value; } } public int Index { get { return index; } set { index = value; } } public override string ToString() { return $"{Name}"; } } public static class CacheHelper { private static Cache cache = new Cache(); public static void Add(string key, object value) { cache.Add(key, value, null, DateTime.Now.AddSeconds(300), TimeSpan.Zero, CacheItemPriority.Normal, null); } public static bool Exist(string key) { if (cache[key] == null) { return false; } else { return true; } } public static object GetValue(string key) { if (Exist(key)) { return cache[key]; } return null; } public static void Remove(string key) { if (Exist(key)) { cache.Remove(key); } } } }