CONNECT C# How to update a text string in a Cell?

I am trying to updated a Text Node containing a single Text Element inside a cell in a DGN file.  Everything seems to work ok until I attempt to replace the existing cell with the modified version using the ReplaceInModel method.  At that point the program will pause for a minute or two and finally generate an error and crash MicroStation CONNECT.

Here is the code I an using to update the text element in the cell.

Can anyone see anything wrong with the code?

A fellow programmer was able to used a similar code written in C++ to update the text element and my code does almost the same thing so I don't understand why it doesn't work.

Note: This method is part of a class that has already stored the Element Ids for the main cell and the text elements located inside the cell.

//------------------------------------------------------------------------------
// setStringId [pubic]
//
// Used to set the ID value for the specifed String ID text elment in the Solar
// rack cell.
//
// Input: uiStringNo - Specifies the index value for the String ID.
// sIdValue - Specifies the ID for for the String ID text element.
//
// Return: SolarRack instance or null.
//------------------------------------------------------------------------------
public void setStringId(uint uiStringNo, string sIdValue)
{
   ElementId stringId = new ElementId();

   bool bFound = false;

   uint i = 1;
   foreach (ElementId currId in StringIdList)
   {
      if (i == uiStringNo)
      {
         stringId = currId;
         bFound = true;
         break;
      }

      i++;
   }

   if (bFound == false)
      return;

   DgnModel activeDgnModel = Session.Instance.GetActiveDgnModel();

   CellQuery rackQuery = null; 

   Element oCell = activeDgnModel.FindElementById(rackElementId);
   if (oCell != null)
   {
      rackQuery = CellQuery.GetAsCellQuery(oCell);
      if (rackQuery == null)
         return;
   }

   rackQuery.ExposeChildren(ExposeChildrenReason.Edit);

   bool bUpdated = false;

   foreach (Element oChildElm in rackQuery.GetChildren())
   {
      if (oChildElm.ElementId != stringId)  
         continue;

      using (TextEdit textEdit = TextEdit.GetAsTextEdit(oChildElm))
      {
         if (textEdit != null)
         {
            DPoint3d origin = DPoint3d.Zero;
            DMatrix3d orientation = DMatrix3d.Zero;

            textEdit.GetSnapOrigin(out origin);
            textEdit.GetOrientation(out orientation);

            TextQueryOptions textOptions = new TextQueryOptions
            {
               ShouldIncludeEmptyParts = false,
               ShouldRequireFieldSupport = false
            };

            TextPartIdCollection textParts = textEdit.GetTextPartIds(textOptions);

            TextBlockProperties textBlockProps = null;
            ParagraphProperties paragraphProps = null;
            RunProperties runProps = null;

            using (TextBlock textBlock = textEdit.GetTextPart(textParts[0]))
            {
               if (textBlock != null)
               {
                  textBlockProps = textBlock.GetProperties();
                  paragraphProps = textBlock.GetParagraphPropertiesForAdd();
                  runProps = textBlock.GetRunPropertiesForAdd();
               }
            }

            if (textBlockProps != null && paragraphProps != null && runProps != null)
            {
               using (TextBlock newTextBlock = new TextBlock(textBlockProps, paragraphProps, runProps, activeDgnModel))
               {
                  textBlockProps.Dispose();
                  paragraphProps.Dispose();
                  runProps.Dispose();

                  if (newTextBlock != null)
                  {
                     newTextBlock.AppendText("Test");
                     newTextBlock.SetUserOrigin(origin);
                     newTextBlock.SetOrientation(orientation);

                     if (textEdit.ReplaceTextPart(textParts[0], newTextBlock) == TextReplaceStatus.Success)
                        bUpdated = true;
                  }
               }
            }
         }
      }
   }

   if (bUpdated)
      rackQuery.ReplaceInModel(oCell);
}

Parents
  • Can anyone see anything wrong with the code?

    It's not formatted as code.  Consequently, it's hard to read.  Follow the Forum Guidelines.

    Use XML Comments

    //  Return: SolarRack instance or null

    The method returns void, not an instance of a SolarRack.

    setStringId [pubic]

    I have pubic hair, but no pubic strings.

    Frankly, there's no point in using comments if those comments are misleading or inaccurate.  If you're using Viz Studio or Visual Studio Code, then use Microsoft's code XML comments.  Those editors are smart enough to check your comments.  IntelliSense uses those XML comments to help you code better.

    Undeclared Variables

    Your code introduces undeclared variables.  For example, we have to guess what these do...

    • rackElementId
    • StringIdList

    Refactor

    That large, intractable method could better be broken down into smaller functions that are easier to follow.  For example, this code could be replace with an equivalent method...

    bool bFound = false;
    
       uint i = 1;
       foreach (ElementId currId in StringIdList)
       {
          if (i == uiStringNo)
          {
             stringId = currId;
             bFound = true;
             break;
          }
    
          i++;
       }
    
       if (bFound == false)
          return;

    And put into this method...

    /// <summary>Attempt to find a string ID by index.</summary>
    /// <returns>True if index is valid.</returns>
    bool StringIndexExists (uint uiStringNo, List<ElementId> StringIdList)

    That makes it more obvious what the code is expected to do.  Whoever is maintaining your code in two years (probably you) will be grateful for code that is easier to read, declares its purpose and provides useful comments.

     
    Regards, Jon Summers
    LA Solutions

Reply
  • Can anyone see anything wrong with the code?

    It's not formatted as code.  Consequently, it's hard to read.  Follow the Forum Guidelines.

    Use XML Comments

    //  Return: SolarRack instance or null

    The method returns void, not an instance of a SolarRack.

    setStringId [pubic]

    I have pubic hair, but no pubic strings.

    Frankly, there's no point in using comments if those comments are misleading or inaccurate.  If you're using Viz Studio or Visual Studio Code, then use Microsoft's code XML comments.  Those editors are smart enough to check your comments.  IntelliSense uses those XML comments to help you code better.

    Undeclared Variables

    Your code introduces undeclared variables.  For example, we have to guess what these do...

    • rackElementId
    • StringIdList

    Refactor

    That large, intractable method could better be broken down into smaller functions that are easier to follow.  For example, this code could be replace with an equivalent method...

    bool bFound = false;
    
       uint i = 1;
       foreach (ElementId currId in StringIdList)
       {
          if (i == uiStringNo)
          {
             stringId = currId;
             bFound = true;
             break;
          }
    
          i++;
       }
    
       if (bFound == false)
          return;

    And put into this method...

    /// <summary>Attempt to find a string ID by index.</summary>
    /// <returns>True if index is valid.</returns>
    bool StringIndexExists (uint uiStringNo, List<ElementId> StringIdList)

    That makes it more obvious what the code is expected to do.  Whoever is maintaining your code in two years (probably you) will be grateful for code that is easier to read, declares its purpose and provides useful comments.

     
    Regards, Jon Summers
    LA Solutions

Children
No Data