.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ObjectModified event

16 REPLIES 16
SOLVED
Reply
Message 1 of 17
BellwetherBill
3805 Views, 16 Replies

ObjectModified event

I'm writing an event handler to trap a polyline being modified with the ObjectModified Event. Right now it works but when I grip edit the polyline I sometimes get only one event fired but sometimes I get multiple events fired. It seems like when I get multiple events fired I get one for every grip...or one for each vertex and each segment?

 

Any suggestions on how I can trap just the last event? I only need the polyline for reading once it is completely updated. Or, I suppose if I could trap a vertex changing somehow then I could do something with that.

 

Thanks.

16 REPLIES 16
Message 2 of 17
Irvin
in reply to: BellwetherBill

What you could do is to handle the modifyed event and add the objectid from the entity to a list. And check if the list has the objectid then don't add it.

 

Then handle your code your code in the command ended event itterate true the list. And then clear the list..

 

Hope this helps. This senario can be used when you need transactionhandling in autocad events.

 

Kind regards,

 

Irvin

Message 3 of 17
BellwetherBill
in reply to: Irvin

Irvin,

 

That worked out perfect. Thanks for your advise.

 

Bill

Message 4 of 17
daverode
in reply to: BellwetherBill

I'm new to autocad custimizatin and I'm trying to capture the object modified event for attribute change. It sounds similiar to what your doing. Is there anyway you could give me a sample of your code to get me started. I'm using vb.net

 

Thanks

Dave

Message 5 of 17

Dave,

Here is some code. I tried to strip out all the custom classes and dependencies specific to my usage. What's left I beleive may be helpful to you. I used ideas and code snipits from reading other posts on events. Another specific contributor that is notable is arcticad and his reply on "Document Change Event".

 

Good luck.

 

{code}

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput

 

Public Class AppEventsClass

    Implements Autodesk.AutoCAD.Runtime.IExtensionApplication

    Private mIdCol As List(Of ObjectId)        'a collection of ObjectId's for use in the command ended event handler
    Private DocMan As DocumentCollection
    Private db As Database
    Private doc As Document

 

    Public Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize

        mIdCol = New List(Of ObjectId)

        DocMan = Application.DocumentManager

        AddHandler DocMan.DocumentCreated, AddressOf callback_documentCreated

        initEvents()

    End Sub

 

    Public Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate

        RemoveHandler DocMan.DocumentCreated, AddressOf callback_documentCreated

        RemoveHandler doc.CommandEnded, AddressOf callback_CommandEnded
        RemoveHandler db.ObjectModified, AddressOf callback_ObjectModified

 

        mIdCol.Clear()

    End Sub

 

    Private Sub initEvents()

        For Each doc In DocMan
            db = doc.Database

            AddHandler doc.CommandEnded, AddressOf callback_CommandEnded
            AddHandler db.ObjectModified, AddressOf callback_ObjectModified

        Next

    End Sub

 

    Private Sub callback_documentCreated(ByVal sender As Object, ByVal e As DocumentCollectionEventArgs)
        initEvents()
    End Sub

 

    Private Sub callback_CommandEnded(ByVal sender As Object, ByVal e As CommandEventArgs)

        If mSIdCol.Count > 0 Then

            Dim ObjID As ObjectId

            For Each ObjID In mIdCol
                Dim Struct As New cStructure(ObjID)
                Struct.Rebuild()

                Struct = Nothing
            Next

            mIdCol.Clear()
        End If

    End Sub

 

    Private Sub callback_ObjectModified(ByVal sender As Object, ByVal e As ObjectEventArgs)
        If Not mIdCol.Contains(e.DBObject.Id) Then

         mIdCol.Add(e.DBObject.Id)

        End If

    End Sub

 

End Class

{code)

Message 6 of 17
daverode
in reply to: BellwetherBill

Hi

 

Thanks for the help. I've gotten as far as getting the objectmodified event to fire, but I'm not sure how to filter for which command was used or how to tell if an attribute has been updated. Do you know of any books or sites that might be helpful on this subject? I got vb.net programming level 1 by Jerry Winters, but there's not much in it on event handlers

 

thanks again for your help

 

Dave

Message 7 of 17
BellwetherBill
in reply to: daverode

You can check for an attribute in the ObjectModified even handler. Test e.DBObject.Id.ClassName. If it matches what you're looking for you can add to the collection.

 

I don't have access to my documentation but there is a Property or method in the CommandArgs for the command name.

 

If you download the ObjectArx documentation you can find lots of information.

Message 8 of 17
BellwetherBill
in reply to: daverode

Sorry, Should have been e.DBObject.Id.ObjectClass.Name.

 

My code reads

 

If e.DBObject.Id.ObjectClass.Name. = "AcDbPolyline" then

   ''do some stuff to polylines

End If

 

I downloaded the ObjectArx 2012 documentation and it has some new stuff in the Managed Class Reference.

Message 9 of 17
daverode
in reply to: BellwetherBill

Still having trouble with this. I've gotten the object modified event to fire but it fires about 15 times every time an object is modified. Any clue as to why this is happening?

Message 10 of 17

Can you post your code to look at?

 

The ObjectModified will fire a lot. There are many things that will cause this to fire on the same object. Not to mention that it fires no matter which object is modified. That's why I added the collection to hold the ObjectId of the entity I wanted to trap. Then I handle it once in the command ended event.

Message 11 of 17
daverode
in reply to: BellwetherBill

            AddHandler myDB.ObjectModified, AddressOf callback_ObjectModified
            AddHandler myDoc.CommandEnded, AddressOf callback_CommandEnded
        End Using
    End Sub
    Private Sub callback_ObjectModified(ByVal sender As Object, ByVal e As ObjectEventArgs)
        Dim myBlockRef As BlockReference = e.DBObject.Id.GetObject(OpenMode.ForRead)
        Dim BTR As BlockTableRecord = myBlockRef.BlockTableRecord.GetObject(OpenMode.ForRead)
        MsgBox(myBlockRef.Layer)' & vbCr & BTR.Name)
        If Not IDList.Contains(e.DBObject.Id) Then
            IDList.Add(e.DBObject.Id)
        End If
    End Sub
    Private Sub callback_CommandEnded(ByVal sender As Object, ByVal e As CommandEventArgs)
        If IDList.Count > 0 Then
            Dim objid As ObjectId
            For Each objid In IDList
                MsgBox("aaaaaaahhhhhh")
            Next
            IDList.Clear()
        End If
    End Sub

 Here is some of the code (basically copying yours) I'm not sure how to test for the block name and layer of the object I modified. Like I said I'm really new at this and appreciate all your help. I'm still at the point where I have to add these events manually with the netload and commandmethods. I'd be willing to pay you for some phone help if this is to much to accomplish through email.

 

once again thanks for your time

 

Dave

Message 12 of 17
daverode
in reply to: BellwetherBill

    Private Sub callback_ObjectModified(ByVal sender As Object, ByVal e As ObjectEventArgs)
        Dim trans As Transaction = e.DBObject.Database.TransactionManager.StartTransaction
        Try
            Dim obj As Object = trans.GetObject(e.DBObject.Id, OpenMode.ForRead)
            If obj.GetType.Name.ToString = "BlockReference" Then
                If Not IDList.Contains(e.DBObject.Id) Then
                    IDList.Add(e.DBObject.Id)
                    MsgBox(obj.GetType.Name.ToString)
                    Dim myBlockRef As BlockReference = e.DBObject.Id.GetObject(OpenMode.ForRead)
                    Dim BTR As BlockTableRecord = myBlockRef.BlockTableRecord.GetObject(OpenMode.ForRead)
                    MsgBox(BTR.Name)
                End If
            End If
        Catch ex As Exception

        End Try
        trans.Dispose()
    End Sub
    Private Sub callback_CommandEnded(ByVal sender As Object, ByVal e As CommandEventArgs)
        If IDList.Count > 0 Then
            Dim objid As ObjectId

            For Each objid In IDList
                MsgBox(e.GetType.ToString)
            Next
            IDList.Clear()
        End If
    End Sub

 

I got a little farther than earlier but I'm still not sure how to get blockref name in the commandended event

Message 13 of 17
BellwetherBill
in reply to: daverode

Dave,

 

Sorry for the delay. I am still very new to .NET as well and have not done much with block references. I will look at this and help where I can but you should at least know that I'm not well versed in this language.

 

That said try using this in your object modified event. Then do the work in command ended event. I don't think you want to try opening the object that called the event.

 

  If e.DBObject.Id.ObjectClass.Name = "AcDbAttribute" Then 
    IDList.Add(e.DBObject.Id)

  End If

 

Message 14 of 17
BellwetherBill
in reply to: daverode

Then try this in your Command ended event.

 

    For Each ObjID In IDList

              Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database

              Using trans As Transaction = db.TransactionManager.StartTransaction
                  Dim Myatt As AttributeReference = trans.GetObject(ObjID, OpenMode.ForRead, False)
                  MsgBox(Myatt.TextString)
              End Using

     Next

Message 15 of 17
daverode
in reply to: BellwetherBill

Thanks

I'll try that and get back to you

Message 16 of 17
daverode
in reply to: daverode

 

    Private Sub callback_ObjectModified(ByVal sender As Object, ByVal e As ObjectEventArgs)
        Dim trans As Transaction = e.DBObject.Database.TransactionManager.StartTransaction
        Try
            Dim obj As Object = trans.GetObject(e.DBObject.Id, OpenMode.ForRead)
            If obj.GetType.Name.ToString = "BlockReference" Then
                If Not IDList.Contains(e.DBObject.Id) Then
                    IDList.Add(e.DBObject.Id)
                    Debug.Print(e.DBObject.Id.ToString)
                    Debug.Print(sender.ToString)
                    MsgBox(obj.GetType.Name.ToString)
                    Dim myBlockRef As BlockReference = e.DBObject.Id.GetObject(OpenMode.ForRead)
                    MsgBox(myBlockRef.ObjectId.ToString)
                    Dim BTR As BlockTableRecord = myBlockRef.BlockTableRecord.GetObject(OpenMode.ForRead)
                    MsgBox(BTR.Name)
                End If
            End If
        Catch ex As Exception
        End Try
        trans.Dispose()
    End Sub
    Private Sub callback_CommandEnded(ByVal sender As Object, ByVal e As CommandEventArgs)
        Dim myDwg As Document = DocumentManager.MdiActiveDocument
        Dim myDB As Database = ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database
        Try
            For Each objid In IDList
                Using myTrans As Transaction = myDwg.TransactionManager.StartTransaction
                    Dim myTags As New ArrayList
                    Dim myStrings As New ArrayList
                    myTags.Add("FunctionText")
                    myStrings.Add("This is a test")
                    SetAttributes(objid, myTags, myStrings)
                    myTrans.Commit()
                End Using
            Next
            IDList.Clear()
            Catch ex As Exception
        End Try
        RemoveHandler myDB.ObjectModified, AddressOf callback_ObjectModified
        RemoveHandler myDoc.CommandEnded, AddressOf callback_CommandEnded
    End Sub


    Public Sub SetAttributes(ByVal BlockID As ObjectId, ByVal TagList As ArrayList, ByVal StringList As ArrayList)
        Dim myTransMan As DatabaseServices.TransactionManager
        Dim myTrans As DatabaseServices.Transaction
        Dim myDwg As Document

        myDwg = Application.DocumentManager.MdiActiveDocument
        myTransMan = myDwg.TransactionManager
        myTrans = myTransMan.StartTransaction

        Dim myBlockRef As BlockReference
        Dim myAttColl As AttributeCollection
        myBlockRef = BlockID.GetObject(OpenMode.ForWrite, False)
        myAttColl = myBlockRef.AttributeCollection
        Dim myEnt As ObjectId
        Dim myAttRef As AttributeReference
        For Each myEnt In myAttColl
            myAttRef = myEnt.GetObject(OpenMode.ForWrite, False)
            If TagList.Contains(myAttRef.Tag) Then
                Dim X As Integer = TagList.BinarySearch(myAttRef.Tag)
                If X >= 0 Then
                    myAttRef.TextString = StringList(X)
                End If
            End If
        Next
        myTrans.Commit()
        myTrans.Dispose()
        myTransMan.Dispose()
    End Sub

Seams like everthing works great until I try to open up the attref for read then I get an exception...any ideas

 

Thanks

Message 17 of 17
BellwetherBill
in reply to: daverode

Dave,

 

Sorry I haven't looked at this much. I've been right out straight.

 

I see several potential problems I think but have not had time to test. It would be helpfult too if you could tell me what it is you're trying to accomplish. Please post any progress you've made and I'll try to look at it later next week.

 

Bill

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost