using Bentley.DgnPlatformNET; using Bentley.DgnPlatformNET.Elements; using Bentley.MstnPlatformNET; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OPIMMXTOOL { public class CoordinateTool : DgnElementSetTool { public static void InstallNewTool() { CoordinateTool coordinateTool = new CoordinateTool(); coordinateTool.InstallTool(); } public CoordinateTool() : base(0, 0) { } /// <summary> /// 修改元素 /// </summary> /// <param name="element"></param> /// <returns></returns> public override StatusInt OnElementModify(Element element) { /* * 1.检查是不是单元 * 2.检查单元名称 * 3.检查文本是否符合 * 4.替换文本 */ if (element is CellHeaderElement) { CellHeaderElement cellElement = element as CellHeaderElement; if (cellElement.CellName != "PLANTC") { MessageCenter.Instance.ShowErrorMessage("选择错误", "请选择坐标标注单元", false); return StatusInt.Error; } ChildElementCollection childElements = cellElement.GetChildren(); List<Element> textElements = childElements.Where(e => e.ElementType == MSElementType.Text).ToList(); if (textElements.Count == 0) { MessageCenter.Instance.ShowErrorMessage("模型错误", "找不到坐标文本", false); return StatusInt.Error; } CoordinateHelps coordinateHelps = new CoordinateHelps(); foreach (TextElement textEle in textElements) { // IntPtr oldRef = textEle.GetNativeElementRef(); TextEdit textEdit = textEle.AsTextEdit(); if (textEdit==null||!textEdit.IsTextElement) { MessageCenter.Instance.ShowErrorMessage("位置错误", "", false); continue; } TextPartIdCollection txtPartIdCol = textEdit.GetTextPartIds(new TextQueryOptions()); foreach (TextPartId curVal in txtPartIdCol) { TextBlock txtBlock = textEdit.GetTextPart(curVal); string oldString = txtBlock.ToString(); string newText = coordinateHelps.GetNewString(oldString); Caret caretStart = txtBlock.CreateStartCaret(); Caret caretEnd = txtBlock.CreateEndCaret(); if (string.IsNullOrEmpty(newText)) { MessageCenter.Instance.ShowErrorMessage("坐标获取错误", oldString, false); continue; } txtBlock.ReplaceText(newText, caretStart, caretEnd); textEdit.ReplaceTextPart(curVal, txtBlock); //textEdit.ReplaceInModel(textEle); textEle.ReplaceInModel(textEle); } //TextQuery txtQuery = TextQuery.GetAsTextQuery(textEle); //TextPartIdCollection txtPartIdCol = txtQuery.GetTextPartIds(new TextQueryOptions()); //foreach (TextPartId curVal in txtPartIdCol) //{ // TextBlock txtBlock = txtQuery.GetTextPart(curVal); // Caret caretStart = txtBlock.CreateStartCaret(); // Caret caretEnd = txtBlock.CreateEndCaret(); // string oldString=txtBlock.ToString(); // string newText = coordinateHelps.GetNewString(oldString); // if (string.IsNullOrEmpty(newText)) // { // MessageCenter.Instance.ShowErrorMessage("坐标获取错误", oldString, false); // continue; // } // txtBlock.ReplaceText(newText, caretStart, caretEnd); // // Element newTextElement = null; // TextHandlerBase txtHandlerBase = TextHandlerBase.CreateElement(null, txtBlock); // textEle.ReplaceInModel(txtHandlerBase); // // element.ReplaceInModel(textEle); } return StatusInt.Success; } else { MessageCenter.Instance.ShowErrorMessage("选择错误", "请选择坐标标注单元", false); return StatusInt.Error; } } protected override void OnRestartTool() { InstallNewTool(); } protected override bool NeedAcceptPoint() { return false; } } }
在OPIM出轴测图的时候,因为我这需要的的坐标表示方式在软件中并不支持,因此需要做一个工具选择轴测图中的坐标标注,然后读取文本后改成我们需要的方式。在OnElementModify()方法中获取到坐标标注单元,然后读取里面的文本元素,读取文本内数据,处理成我这需要的格式,替换文本。但是目前程序跑到ReplaceInModel()软件就会崩,请老师指导一下,这个该怎么写。
把ReplaceInModel去掉不执行试试,OnElementModfiy返回Success的时候,后台会用修改后的元素替换原来的元素。
软件不会崩了,但是修改并没有生效。
改用老的COM接口可以,如下代码所示。其中SampleMixed.ElementOperation.ConvertToInteropEle是将新Element转成老的COM框架下的元素,请参考这篇博文:https://communities.bentley.com/communities/other_communities/bdn_other_communities/w/chinabdn-wiki/41035/c-cli-addins,这篇是通过c++/cli语言写的转换,在纯c#环境下也能实现,可以参考这篇博文:communities.bentley.com/.../element
public override StatusInt OnElementModify(Element element) { if (element is CellHeaderElement) { BIM.Element eleCom = SampleMixed.ElementOperation.ConvertToInteropEle(element); BIM.CellElement comEl = (BIM.CellElement)eleCom; comEl.ResetElementEnumeration(); var subEls = comEl.GetSubElements(); while (subEls.MoveNext()) { var subEl = subEls.Current; if (subEl.Type == BIM.MsdElementType.Text) { BIM.TextElement curTxtEle = (BIM.TextElement)subEl; curTxtEle.Text = "aaa"; curTxtEle.Rewrite(); } else if (BIM.MsdElementType.TextNode == subEl.Type) { BIM.TextNodeElement curTxtNodeEle = (BIM.TextNodeElement)subEl; BIM.ElementEnumerator curSubEles = curTxtNodeEle.GetSubElements(); while (curSubEles.MoveNext()) { var curSubEle = curSubEles.Current; if (curSubEle.Type == BIM.MsdElementType.Text) { BIM.TextElement curTxtEle = (BIM.TextElement)curSubEle; curTxtEle.Text = "aaa"; curTxtEle.Rewrite(); } } } } }
Answer Verified By: Wulix
成功,附上代码:
public override StatusInt OnElementModify(Element element) { /* * 1.检查是不是单元 * 2.检查单元名称 * 3.检查文本是否符合 * 4.替换文本 */ if (element is CellHeaderElement) { CoordinateHelps coordinateHelps = new CoordinateHelps(); long id = element.ElementId; BIM.Application app = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp; BIM.Element comElement = app.ActiveModelReference.GetElementByID(id); BIM.CellElement cell = comElement.AsCellElement(); if (cell.Name != "PLANTC") { MessageCenter.Instance.ShowErrorMessage("选择错误", "请选择坐标标注单元", false); return StatusInt.Error; } var subEles = cell.GetSubElements(); while (subEles.MoveNext()) { var subEle = subEles.Current; if (subEle.Type == BIM.MsdElementType.Text) { BIM.TextElement currentTextEle = (BIM.TextElement)subEle; string oldString = currentTextEle.Text; string newText = coordinateHelps.GetNewString(oldString); currentTextEle.Text = newText; currentTextEle.Rewrite(); } } } else { MessageCenter.Instance.ShowErrorMessage("选择错误", "请选择坐标标注单元", false); } return StatusInt.Error; }