【MSCE C#]修改单元里的文本,一直不成功.软件崩溃

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;
            }