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

ObjectModified event

19 REPLIES 19
Reply
Message 1 of 20
Anonymous
1637 Views, 19 Replies

ObjectModified event

I code in VB

 

I want to trap the ObjectModified event.

If I do AutoCad crashes when I close it down.

 

What I first did was to

Dim WithEvents CurDb as Database

but I realised that CurDb only related to the Active Document, so I removed the WithEvents and used a AddHandler, and so

In my New event (which seems to be fired the first time a execute one of my commands) I entered:-

      DocMan = Application.DocumentManager

     AddHandler DocMan.DocumentActivated, AddressOf DocumentActivated

      AcadDoc = DocMan.MdiActiveDocument

      CurDb = AcadDoc.Database

 

and so in my DocumentActivated I entered this code.

     

     RemoveHandler CurDb.ObjectModified, AddressOf ObjectModified ' assuming previous CurDb

      AcadDoc = DocMan.MdiActiveDocument

      CurDb = AcadDoc.Database

     AddHandler CurDb.ObjectModified, AddressOf ObjectModified

 

when I debug, I can step through this code without a problem.

but I crash exiting AutoCad

 

I've looked everywhere for a solution before asking you lot. Please help me again and thanks.

19 REPLIES 19
Message 2 of 20
Alfred.NESWADBA
in reply to: Anonymous

HI,

 

first idea: your EventHandler (that you create at "DocumentActivated") is not released when AutoCAD closes the document?

You should release the EventHandler for each Document when it's closing.

 

HTH, - alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 20
Anonymous
in reply to: Anonymous

I found the problem!

 

  

FriendSub ObjectModified(ByVal sender AsObject, ByVal e As Autodesk.AutoCAD.DatabaseServices.ObjectEventArgs)

     

If e.DBObject.IsWriteEnabled ThenExitSub

      Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & e.DBObject.Id.ObjectClass.Name &

" modified")

  

End Sub

 

Application.DocumentManager.MdiActiveDocument.Editor doesn't exist when closing drawing.

Message 4 of 20
01688686718
in reply to: Anonymous

please help

Now i have a new question. i wanna make a event,

when i change the start point of line in cad screen then raise event startPointChange. help me raise event.

thank you!!!

ko0ls
Message 5 of 20

So you want to raise your own custom events. That's not an AutoCAD specific question - its generic .NET programming. I recommend searching for 'raise event' on MSDN or other Microsoft forums. For example, here is an VB.NET example from MSDN - http://msdn.microsoft.com/en-us/library/h7a2kh64%28v=vs.90%29.aspx

 

 

Cheers,

Stephen Preston
Autodesk Developer Network
Message 6 of 20

No, i knew how to raise event, now i wanna know where is the sub to put raise event?

ko0ls
Message 7 of 20

in autocad drawing, when i move a object then location of it changed so i wanna know code to get the event objectLocationChange.

ko0ls
Message 8 of 20
norman.yuan
in reply to: 01688686718

Basically, you can handle Database.ObjectModified event and in the event handler, you test if the modified entity is an Line type (or other type of your interest). If it is Line, then you raise your own custom event.

 

However, in ObjectModified event, you only know the entity was modified, but you do not know what change was made (moving/stretching, rotating...). if you want to riase your own event only when specific action (say, moving), then you need to handle other events that happen before ObjectModified, such as CommandWillStart and try to find the targeting entity (Line, in your case) and save its "before-change" state (start point/endpoint). so that in ObjectModified event handler, you can compare how the entity is changed. Man, it is quite complicated and could add huge overhead to AutoCAD, if the drawing has tons of Line entities.

 

Another possible approach might be to use TransformOverrule and override its TransformedBy virtue method (e.g raise your custom event from there). I have not tried as your requirement, but thought worth look into.

Norman Yuan

Drive CAD With Code

EESignature

Message 9 of 20
01688686718
in reply to: norman.yuan

thank you so much, i think it is worth for me.
i have a project about autocad.net but i'm beginer. i hope you can help me
when i have happen.[?]
ko0ls
Message 10 of 20
01688686718
in reply to: norman.yuan

can you help me?

I have a line, i want if i select the line then my palette is visible. You can show me where i have register or raise event selected object?

ko0ls
Message 11 of 20

Hi Norman!

I think it is possible to compare state of entity in two events:
1) Database.ObjectOpenedForModify - before modification

2) Database.ObjectModified - after modification

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 12 of 20

can you explain by some example.

ko0ls
Message 13 of 20
mzakiralam
in reply to: 01688686718

you might try the below code to show palette while a line is selected.

 

 Dim m_ps As Autodesk.AutoCAD.Windows.PaletteSet = Nothing
<CommandMethod("PS")> Public Sub PaletteShowforLine() Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor 'select a line Dim peo As PromptEntityOptions = New PromptEntityOptions(vbLf & "Select a Line:") Dim per As PromptEntityResult = ed.GetEntity(peo) If per.Status <> PromptStatus.OK Then Return End If 'start transaction Using tx As Transaction = db.TransactionManager.StartTransaction() 'get the entity Dim ent As Entity = tx.GetObject(per.ObjectId, OpenMode.ForRead) 'if entity type is line the raise the palette event If TypeOf ent Is Line Then PaletteShow() End If tx.Commit() End Using End Sub Public Sub PaletteShow() 'palette show event If m_ps Is Nothing Then m_ps = New Autodesk.AutoCAD.Windows.PaletteSet("My Palette") Dim userCtrl As UserControl1 = New UserControl1() m_ps.Add("My Palette", userCtrl) End If m_ps.Visible = True End Sub

 

Message 14 of 20
01688686718
in reply to: mzakiralam

no. I mean i don't wanna to use editor.prompt. In the drawing, i click a random object then my palette will show although i don't send command to command line.

ko0ls
Message 15 of 20
mzakiralam
in reply to: 01688686718

In that case you have to add editor event handler. you can start with below code:

Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
'add handler for selection added
AddHandler ed.SelectionAdded, AddressOf LineSelection

Public Sub LineSelection(sender As Object, e As SelectionAddedEventArgs)
        For Each id As ObjectId In e.AddedObjects.GetObjectIds
            Using tx As Transaction = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction()
                Dim ent As Entity = tx.GetObject(id, OpenMode.ForRead)
                If TypeOf ent Is Line Then
                    'add palette show up event
                End If
            End Using
        Next
    End Sub

 

Message 16 of 20

Thank you Alex for prompting me the ObjectOpenedForModify event. Yes, it can be used in conjunction with ObjectModified to watch specific entities being changed.

 

To 01688686718:

 

I put together some code quickly that watches Line entitiy or entities being changed:

 

using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

[assembly: CommandClass(typeof(ObjectModifiedTest.MyCommands))]

namespace ObjectModifiedTest
{
    public class LineInfo
    {
        public ObjectId LineId { private set; get; }
        public Point3d StartPoint { private set; get; }
        public Point3d EndPoint { private set; get; }
        public bool Changed { private set; get; }

        public LineInfo(Line line)
        {
            LineId = line.ObjectId;
            StartPoint = line.StartPoint;
            EndPoint = line.EndPoint;
            Changed = false;
        }

        public void TestChange(Line line)
        {
            if (line.ObjectId == this.LineId &&
                (line.StartPoint != this.StartPoint &&
                line.EndPoint != this.EndPoint))
                Changed = true;
            else
                Changed = false;
        }
    }

    public class MyCommands
    {
        private Dictionary<ObjectId, LineInfo> _modifiedLines = null;
        private bool _watch = false;

        [CommandMethod("WatchLine")]
        public void RunMyCommand()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            if (!_watch)
            {
                StartWatchLineChange(dwg);
                _watch = true;
            }
            else
            {
                _watch = false;
                StopWatchLineChange(dwg);
            }

            Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
        }

        private void StartWatchLineChange(Document dwg)
        {
            dwg.CommandWillStart += dwg_CommandWillStart;
            dwg.CommandEnded += dwg_CommandEnded;
            dwg.Editor.WriteMessage("\nLine change watching is on.");
        }

        private void dwg_CommandWillStart(object sender, CommandEventArgs e)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            _modifiedLines = new Dictionary<ObjectId, LineInfo>();

            db.ObjectOpenedForModify += Database_ObjectOpenedForModify;
            db.ObjectModified += Database_ObjectModified;
        }

        private void dwg_CommandEnded(object sender, CommandEventArgs e)
        {
            if (e.GlobalCommandName.ToUpper().Contains("WATCHLINE")) return;
            
            Database db = HostApplicationServices.WorkingDatabase;

            db.ObjectOpenedForModify -= Database_ObjectOpenedForModify;
            db.ObjectModified -= Database_ObjectModified;

            ShowChangedLines();
        }

        private void Database_ObjectModified(object sender, ObjectEventArgs e)
        {
            if (e.DBObject is Line)
            {
                if (_modifiedLines.ContainsKey(e.DBObject.ObjectId))
                {
                    _modifiedLines[e.DBObject.ObjectId].TestChange(e.DBObject as Line);

                }
            } 
        }

        private void Database_ObjectOpenedForModify(object sender, ObjectEventArgs e)
        {
            if (e.DBObject is Line)
            {
                if (!_modifiedLines.ContainsKey(e.DBObject.ObjectId))
                {
                    _modifiedLines.Add(
                        e.DBObject.ObjectId, new LineInfo(e.DBObject as Line));
                }
            }
        }

        private void ShowChangedLines()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            foreach (var info in (from item in _modifiedLines select item.Value))
            {
                ed.WriteMessage(
                    "\nLine {0} changed: {1}", 
                    info.LineId.ToString(), info.Changed.ToString());
            }
        }

        private void StopWatchLineChange(Document dwg)
        {
            dwg.CommandWillStart -= dwg_CommandWillStart;
            dwg.CommandEnded -= dwg_CommandEnded;
            dwg.Editor.WriteMessage("\nLine change watching is off.");
        }
    }
}

 

Please note the command method is NOT a static method, so that the _modifiedLines Dictionary is instantiated by "per document". That is, the event halders are added/removed "per document" when "WATCHLINE" command is executed.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 17 of 20
01688686718
in reply to: mzakiralam

thank you. but my problem don't solve. i do like your post but when i move mouse over my entity, my palette show again. i can't control it. this is my code:

Public Sub show()
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim tran As Transaction = db.TransactionManager.StartTransaction
Dim bt As BlockTable = tran.GetObject(db.BlockTableId, OpenMode.ForRead)
Dim btr As BlockTableRecord = tran.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
objIdCol.Add(btr.AppendEntity(dt))
objIdCol.Add(btr.AppendEntity(ht))
objIdCol.Add(btr.AppendEntity(sh))
'AddHandler HostApplicationServices.WorkingDatabase.ObjectModified, AddressOf HandleEndPointChange
'AddHandler HostApplicationServices.WorkingDatabase.ObjectModified, AddressOf HandleStartPointChange
'AddHandler HostApplicationServices.WorkingDatabase.ObjectModified, AddressOf HandleCircleCenterChange
'AddHandler HostApplicationServices.WorkingDatabase.ObjectModified, AddressOf HandleShLocationChange
AddHandler ed.SelectionAdded, AddressOf LineSelection
tran.AddNewlyCreatedDBObject(dt, True)
tran.AddNewlyCreatedDBObject(ht, True)
tran.AddNewlyCreatedDBObject(sh, True)
tran.Commit()
tran.Dispose()
End Sub
Private Sub LineSelection(ByVal sender As Object, ByVal e As SelectionAddedEventArgs)
For Each id As ObjectId In e.AddedObjects.GetObjectIds
If objIdCol.Contains(id) Then
Using tx As Transaction = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction()
Dim ent As Entity = tx.GetObject(id, OpenMode.ForRead)
If TypeOf ent Is Line Then
'add palette show up event
Dim pl As New Container1
pl.InP = Me
pl.hienthi()
End If
End Using
End If
Next
End Sub

ko0ls
Message 18 of 20
01688686718
in reply to: mzakiralam

when i wanna unselect a object, what event i must use? Does event is SelectionRemoved?

ko0ls
Message 19 of 20
mzakiralam
in reply to: 01688686718

Hi ,

you can follow below link. Same Problem like you has described there and one Suggestion has been made. you can try with that. In the mean time I will try to look on code to make it clean.

http://forums.autodesk.com/t5/NET/editor-SelectionAdded-event/m-p/3042624/highlight/true#M23775

You can try to have a look by using SelectionRemoved Event and see what is the effect. I have to try also.
Message 20 of 20
01688686718
in reply to: mzakiralam

i hope you can help me handle event deselection such as selectionRemoved

ko0ls

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