Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

How to react to an attribute being changed?

nshupeFMPE3
Advocate

How to react to an attribute being changed?

nshupeFMPE3
Advocate
Advocate

I have two kinds of blocks that need to stay "in sync" which looks like this. 
There is block A which has a numeric identifier as an Attribute. Then there can be 1-10+ of block be that are "associated" with block A and need to have the same identifier. When the block B's are inserted the user inputs the identifier into block B's attribute. 

There can be many of these one-to-many associations ie. Block A has 5 block B's all with #1, Block C has 4 block D's with #2 etc

I'm trying to react to the situation where the attribute for block A is changed for example from 1 to 2. 

I'd like all the Block B's with their attribute as 1 to change their attribute value to 2. 

So far I have added an event watcher to the attribute for block A when it is added to the drawing

private void AttachNumberWatcher(object sender, ObjectEventArgs e)
        {
            if (!e.DBObject.GetType().Equals(typeof(AttributeReference))) return;
            AttributeReference att = e.DBObject as AttributeReference;
            if (!att.Tag.Equals("ATT#")) return;
            att.Modified += Changed_Number;

        }


Then when the Attribute is modified I check for XData. The XData value is suppose to equal the attributes current text value. If it does not match, then the XData value is the old value and the current text value of the attribute is what all the Block B's should be changed to. 

public static void Changed_Number(object sender, EventArgs e)
        {
            AttributeReference att = sender as AttributeReference;
            using (Transaction tr = att.Database.TransactionManager.StartOpenCloseTransaction())
            {
                ResultBuffer xrecord = att.XData;
                if (xrecord == null)
                {
                    _needToProcess.Add(att.ObjectId);
                    att.ObjectClosed += AddXdataToAttribute;
                    tr.Abort();
                    return;
                }
                string recordedNum = xrecord.AsArray()[1].Value as string;
                if (att.TextString == recordedNum)
                {
                    tr.Abort();
                    return;
                }
                UpdateBlockB(recordedNum, att.TextString);
                _needToProcess.Add(att.ObjectId);
                att.ObjectClosed += AddXdataToAttribute;
                tr.Abort();
            }

        }


The problem I was having was trying to add XData to an attribute that didn't have any yet, because I would get an eWasNotifying crash. So I created a separate function to add the XData after the attribute was closed, which is happening at line 10 and 22 above. I was reacting to att.Database.ObjectAppend but this doesn't trigger when the attribute has had it's value changed, so the Xdata event on line 22 never triggers. 

private static void AddXdataToAttribute(object sender, EventArgs e)
        {
            foreach (ObjectId id in _needToProcess)
            {
                using (Transaction tr = id.Database.TransactionManager.StartOpenCloseTransaction())
                {
                    AttributeReference att = tr.GetObject(id, OpenMode.ForWrite, false, true) as AttributeReference;
                    att.XData = new ResultBuffer(new TypedValue((int)DxfCode.ExtendedDataRegAppName, RegAppName), new TypedValue((int)DxfCode.ExtendedDataAsciiString, att.TextString));
                    tr.Commit();
                }
            }
            _needToProcess.Clear();
            Database db = sender as Database;
            //remove event watcher

        }


Is there a better/cleaner way to be doing what I am trying to do? 

0 Likes
Reply
357 Views
1 Reply
Reply (1)

Virupaksha_aithal
Autodesk Support
Autodesk Support

Hi,

 

Generally, it is good practice to make database edits in command end notification compared to any other callback. refer https://www.keanw.com/2008/08/rolling-back-th.html . so, i suggest if possible, see if your workflow supports you to do the database modifications in command ended notification....



Virupaksha Aithal KM
Developer Technical Services
Autodesk Developer Network

0 Likes