Announcements

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

Adding event watcher to copied block

nshupeFMPE3
Advocate

Adding event watcher to copied block

nshupeFMPE3
Advocate
Advocate

What would be the best way for me to add an event watcher to a block that was copied. I want every instance of this block to have its .Modified event subscribed to, but I only know how to subscribe when to the ones that already exist at document open. How would I subscribe to any that get inserted or copied? 

Thanks in advance.

0 Likes
Reply
475 Views
7 Replies
Replies (7)

ActivistInvestor
Advisor
Advisor

You will need to handle the Database. ObjectAppended event.

0 Likes

nshupeFMPE3
Advocate
Advocate

@ActivistInvestor 

So far this is what I have. When a drawing is loading I initialize this class, which finds all the existing blocks and adds the event handler. It also adds the event handler to the Database.ObjectAppended event. Then when I copy the block that is already in model space, and paste it, the event triggers.

When the ObjectAppended event triggers, I check if the item is a block, and if that block is an instance of the one I care about. If it is then I attached the event watcher. 

Weird thing is, the appended triggers two times. I remove the event watcher before adding, which I would think makes sure there is only ever one copy. 

The weird thing is that the new block seems to only have one instance of the event watcher attached. But the original one in the drawing that I copied from, after pasting seems to have two? 

Is it something to do with it being a dynamic block? It only has a visibility with two states and one attribute. I'm at a loss.

 

public FloorInfoEvent()
{
    var allBlock = Active.Editor.SelectAllBlock("FloorInfo");

    if (allBlock.Status != PromptStatus.OK) return;

    ObjectIdCollection ids = new ObjectIdCollection(allBlock.Value.GetObjectIds());
    
    if(ids.Count < 1) return;

    ids.TryForEachRead<BlockReference>(block =>
    {
        block.Modified -= BlockOnModified;
        block.Modified += BlockOnModified;
    });

    Active.Database.ObjectAppended += DatabaseOnObjectAppended;
}

private void DatabaseOnObjectAppended(object sender, ObjectEventArgs e)
{
    BlockReference block = e.DBObject as BlockReference;
    if (block == null || !block.IsInstanceOf("FloorInfo")) return;
    block.Modified -= BlockOnModified;
    block.Modified += BlockOnModified;

}

 

0 Likes

ActivistInvestor
Advisor
Advisor

Events on database objects are implemented as reactors. Reactors can be copied when the database object they are attached to is copied/cloned. Behavior may vary depending on whether you are copying objects within the same database or across databases. Are you sure that in every case where you add a Handler to an object event, you remove any existing Handler first?

0 Likes

nshupeFMPE3
Advocate
Advocate

I'm positive those are the only times that I am adding that Event Handler to the .Modified event. 
Right now I have it working that on start up, the event watcher is attached to existing blocks. But If I CTRL + C (copy) and CTRL + V (paste) the new copy does not trigger the event handler.

0 Likes

ActivistInvestor
Advisor
Advisor

COPYCLIP/PASTECLIP use WBLOCK/INSERT which would not copy reactors, so it is the same scenario that you have if you just INSERT objects from another drawing. 

0 Likes

nshupeFMPE3
Advocate
Advocate

Should I set up a reactor to when an INSERT command ends? Check if its the block type I want and then add the event watchers.

0 Likes

ActivistInvestor
Advisor
Advisor

The Database class has a BeginDeepCloneTranslation 

event that lets you examine the mapping between the source objects and the copies of them that are created in the destination Database. You can use that event to identify the objects that you need to attach event handlers to.

0 Likes