Author Topic: Get BlockReference name from AttributeReference efficiently  (Read 1973 times)

0 Members and 2 Guests are viewing this topic.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Get BlockReference name from AttributeReference efficiently
« on: August 12, 2018, 08:36:58 PM »
I have the need to know if an attribute of a specific class of blocks has been modified. To address this, I have implemented the ObjectModified event of the document. This handles block references only that are named "ZDB*" (I need to know if the blockreference has been modified as well)

Code - C#: [Select]
  1. private void OnObjectModified(object sender, ObjectEventArgs e)
  2. {
  3.     BlockReference br;
  4.     if (e.DBObject.GetType() == typeof(BlockReference))
  5.     {
  6.         br = (BlockReference)e.DBObject.ObjectId.GetObject(OpenMode.ForRead);
  7.     }
  8.     else if (e.DBObject.GetType() == typeof(AttributeReference))
  9.     {
  10.         br = (BlockReference)e.DBObject.OwnerId.GetObject(OpenMode.ForRead);
  11.     }
  12.     try
  13.     {
  14.         if (br.Name.StartsWith("ZDB", True, CultureInfo.CurrentCulture))
  15.         {
  16.             \\Handle this later after the command has ended
  17.             QueueEvent = true;
  18.             br.Close();
  19.             br.Dispose();
  20.         }
  21.     }
  22.     catch {}
  23. }

The compiler complains that Close is depreciated and that I should use a transaction. That seems overkill in this scenario. Honestly, if I didn't have to open the object, I wouldn't have to close it.

Is there a more efficient way of doing this? There could possibly be hundreds if not thousands of iterations during the life of the current command and this is the only way I have of filtering the chaff so I only call the other functions when there is no command active.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Get BlockReference name from AttributeReference efficiently
« Reply #1 on: August 13, 2018, 12:59:45 AM »
hi,

The Objectid.GetObject() method uses the active top transaction (if any).
Within an event hadler, you should use an OpenCloseTransaction or the 'depreciated' Open/Close methods .
You can remove the 'depreciated' warning like this:
Code - C#: [Select]
  1. #pargma warning disable 0618
  2.     // some code using Close/Open methods
  3. #pragma warning restore 0618
Speaking English as a French Frog

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Get BlockReference name from AttributeReference efficiently
« Reply #2 on: August 13, 2018, 09:47:16 AM »
Is there another way to get the block name without opening the blockreference for read? When a blockreference is the object represented by e.DBObject is a block reference, I can just get the name without opening.

Better yet, is there a better way of doing this?
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

n.yuan

  • Bull Frog
  • Posts: 348
Re: Get BlockReference name from AttributeReference efficiently
« Reply #3 on: August 13, 2018, 10:02:42 AM »
Yes, if the e.DBObject is a BlockReference, you do not need to open it as BlockReference by its id. The e.DBObject is open for read. You simply cast it to BlockReference in order to access its Name property.

But if the e.DBObject is AttributReference, its owner (BlockReference is likely open for read by AutoCAD when the ObjectModified even fires, but we simply do not have direct access to it. The only way is via its OwnerId, as you already did.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Get BlockReference name from AttributeReference efficiently
« Reply #4 on: August 13, 2018, 12:42:28 PM »
I could probably simplify the code some but because I like code to understandable by just looking at the code, I'll leave it as it is now.

What I am doing is monitoring changes to the drawing as they pertain to specific block references. If they change, then I need to update the data in my program. I learned really quick that I can't do that immediately because if a command is active, autocad will get a fatal error. Same thing seems to happen in undo though, still working through that issue!
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie