.NET

Reply
Contributor
Mathew.webber
Posts: 19
Registered: ‎07-26-2010
Message 1 of 15 (486 Views)

Responding to the Properties Palette

486 Views, 14 Replies
11-07-2011 08:09 AM

Hi all,


Its my first post so go easy on me  :-o

I am writing in the process of writing a AutoCAD/Civil3D plug-in (in VB.Net) product that needs current detects all of the updates (modified, erased , Unmodified, etc) on my own Entities and then only act on these once. So to this end I am maintaining a list of the affect entities and then processing the 'queue' on Document.CommandEnded.

This worked perfectly for me until I realised that the Properties Palette (and probably others) do not actually perform a command so the command end event is never caught. Obviously the queue will be processed on the next command but it looks sloppy that my data is not updated straight away.

I have seen various blog posts and a similar post on here that suggest using DocumentManager.DocumentLockModeWillChange or Editor.EnteringQuiescentState as the event to detect the end of the edit. However I am finding that no matter which of there I use I am unable to apply my Document Lock and this leads to Access Violations no matter what checks I do passed on the EventArgs.

I believe I have all the right Document locks in place, all in Using Statements so they should be disposed of correctly.

Can anyone point me in the right direction or correct the error of my ways?

Many Thanks!

Mat

ADN Support Specialist
augusto.goncalves
Posts: 390
Registered: ‎04-30-2009
Message 2 of 15 (453 Views)

Re: Responding to the Properties Palette

11-10-2011 04:38 AM in reply to: Mathew.webber

Hi,

 

Instead of processing them on CommandEnd, consider Database.ObjectAppended/Modified/Erased events, it works fine on Palette.

 

When you try change the database from palette, or any other modeless dialog, you need to do it through command or lock the database yourself.

 

Regards,

Augusto Goncalves

Autodesk Developer Network

Regards,



Augusto Goncalves
Autodesk Developer Network
Contributor
Mathew.webber
Posts: 19
Registered: ‎07-26-2010
Message 3 of 15 (443 Views)

Re: Responding to the Properties Palette

11-10-2011 06:12 AM in reply to: augusto.goncalves

Hi Augusto,

 

Thank you for getting back to me. :smileyhappy:

 

Is there away to tell that the event has been thrown as a result of the properties box or that no other changes will occur after the current one? I have looked for this but so far no joy.

 

My issue is that I need to perfom a large number of calculations following any update to my entities. So as a normal command could lead to many of my entities being editted I need to only process them all at the end rather than as they occur, hence why i am storing them in the handlers and then processing the list in CommandEnded.

 

Thanks

 

 

Contributor
Mathew.webber
Posts: 19
Registered: ‎07-26-2010
Message 4 of 15 (411 Views)

Re: Responding to the Properties Palette

11-18-2011 05:00 AM in reply to: Mathew.webber

 

Does anyone have any further thoughts on this?

 

I have been looking into Overrules, but so far have been unable to find away of making them work for this problem.

*Expert Elite*
norman.yuan
Posts: 1,062
Registered: ‎04-27-2009
Message 5 of 15 (397 Views)

Re: Responding to the Properties Palette

11-18-2011 10:08 AM in reply to: Mathew.webber

I amy understand your question wrong, but give it a try.

 

Your question is, if a user edit an entity in Propertie Window (as apposed to do it in AutoCAD editor manually, or run a command), is it possible for your application to know that one or more entities have been changed (due to the changes user made in Properties Window)?

 

If this is you want to know, read on.

 

Properties Window is just a UI tool for user to make changes to entities in drawing database. Once the changes in the properties Windows are committed, the user input will to applied to drawing database and Database.ObjectModified event will occur. This is no different from the situation when entities being modified by a command, or manully directly on Acad editor, or by your code.

 

So, simply handling Database.ObjectModified event would give you the opportunity to track which entities have been modified, regardless it is from command, or from Properties Window. Once you are able to ALWAYS know some objects are modified, then it is up to you to decide how to keep track of them and at what point after the changes your code start doing something (Make sure you are not paint yourself into corner of endless loop of Database.ObjectModified->Your code modify some entities->database.ObjectModified->Your ode modify entities->...).

 

Here code sample:

 

using aApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

namespace PropWinDBObjectChange
{
    public class MyCommands
    {
        private Document _dwg = null;
        private Editor _ed = null;
        private bool _watched = false;

        [CommandMethod("WatchDB")]
        public void WatchDBChange()
        {
            if (!_watched)
            {
                if (_dwg == null)
                {
                    _dwg = aApp.DocumentManager.MdiActiveDocument;
                    _ed = _dwg.Editor;
                }

                _dwg.Database.ObjectModified += 
                    new ObjectEventHandler(Database_ObjectModified);
                _watched = true;
                _ed.WriteMessage(
                    "\nStart watching modified objects in current drawing...\n");
            }
            else
            {
                if (_dwg == null) return;

                _dwg.Database.ObjectModified -= 
                    Database_ObjectModified;
                _watched = false;
                _ed.WriteMessage(
                    "\nWatching modified objects in current drawing stopped\n");
            }
        }

        private void Database_ObjectModified(object sender, ObjectEventArgs e)
        {
            _ed.WriteMessage(
                "\nObject modified: ObjectID={0}", e.DBObject.ObjectId.ToString());
        }
    }
}

 

To see the running effect, Netload the code's DLL; draw a few circles/lines...; enter command "WatchDB" to turn the event handler on; then select different entity and make change to it in Properties Window. You can see the Database.ObjectModified event handler shows entity's ObjectID at command line. Of course, you run a command, such as "move", "stretch", the event handler will also be called.

 

Since through Property Window, user can only modify existing entities (i.e. user cannot create new entity or ersae entity from there), handling Database.ObjectModified would cover whatever change to entity user makes from Properties Window.

 

Contributor
Mathew.webber
Posts: 19
Registered: ‎07-26-2010
Message 6 of 15 (379 Views)

Re: Responding to the Properties Palette

11-21-2011 05:28 AM in reply to: norman.yuan

Thanks again for your input, I do appreciate you guys taking the time to answer me.

I suspect though that I was not as clear as I could be on what the problem is. Maybe some code would help out here to highlight where I am?

 

I have added some code below below that shows my basic setup, obviously my creation of data is a bit more involved and extra data is appended as XRecords but it demostrates the problem. If you move with the cursor the line (after running DrawData) you will see the two messages (Entity Modified & Command Ended), however Properties Palette changes will only give the 'Entity Modified' message as the commanded ended in not thrown.

Public Class App
    Implements Autodesk.AutoCAD.Runtime.IExtensionApplication

    ''' <summary>
    ''' Start app
    ''' </summary>
    Public Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize
        'For now we will Greet the user
        ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbNewLine + "Welcome to My Test App!" + vbNewLine)

        'Add handler for CommandEnded
        AddHandler ApplicationServices.Application.DocumentManager.MdiActiveDocument.CommandEnded, AddressOf CommandEnded

    End Sub

    ''' <summary>
    ''' End App
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate
        'Do something....
    End Sub

    ''' <summary>
    ''' Entity has been modified
    ''' </summary>
    Public Sub EntityModified(ByVal senderObj As Object, ByVal evtArgs As EventArgs)

        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbNewLine + "Entity Changed" + vbNewLine)

        'Store the Entity ID

    End Sub

    ''' <summary>
    ''' Command Has Ended
    ''' </summary>
    Public Sub CommandEnded(sender As Object, e As CommandEventArgs)

        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbNewLine + "Command Ended" + vbNewLine)

        'Process the list of Entity IDs

    End Sub

    ''' <summary>
    ''' Draw my data and add handlers
    ''' </summary>
    <CommandMethod("DrawData")> _
    Public Sub DrawData()

        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim l As Line

        'Lock the document and start a new transation
        Using dl As DocumentLock = acDoc.LockDocument()
            Using myTrans As Transaction = acDoc.TransactionManager.StartTransaction()
                ' Open Model space for write
                Using acBlkTbl As BlockTable = CType(myTrans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead), BlockTable)
                    Using acBlkTblRec As BlockTableRecord = CType(myTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

                        'Draw the entities in loop (for example)

                        'Just adding a single line here
                        l = New Line(New Geometry.Point3d(1, 1, 0), New Geometry.Point3d(100, 100, 0))

                        'Assign to the layer zero
                        l.LayerId = acDoc.Database.LayerZero

                        'Add handlers (only one added in demo)
                        AddHandler l.Modified, AddressOf EntityModified

                        acBlkTblRec.AppendEntity(l)
                        myTrans.AddNewlyCreatedDBObject(l, True)

                        myTrans.Commit()

                    End Using
                End Using
            End Using
        End Using

    End Sub

End Class

 
As you can see the events are all hooked up so I know exactly what changes are happening and I store these. I then process these chanegs at once in the CommandEnded event handler. However This is NOT thrown when a change is made on the properties box so this is where my code falls down.

What I need to find is another event to handle other than command ended (DocumentManager.DocumentLockModeWillChange & Editor.EnteringQuiescentState are not working for me either). Or some way of telling that an change occur as a result of the Properties box (i.e. not part of a command).

Does that help?

Distinguished Contributor
JanetDavidson
Posts: 141
Registered: ‎08-23-2011
Message 7 of 15 (331 Views)

Re: Responding to the Properties Palette

03-15-2012 04:06 PM in reply to: Mathew.webber

Hi Matt.

I stuck at same page. I don't want to have a objectmodifed  event all the time  control my application for the sake of attribute edit .  I handled attedit command. But now user can change attribute from properties windows.Just let you know I don't think EnteringQuiescentstate will help . If you find any other solution let me know please. I ended up telling users not use properties. I feel bad. 

Janet

 

Contributor
Mathew.webber
Posts: 19
Registered: ‎07-26-2010
Message 8 of 15 (319 Views)

Re: Responding to the Properties Palette

03-16-2012 02:21 AM in reply to: JanetDavidson

Hi Janet,

 

I have been in conversation with ADN on the topic as i was getting nowhere. Unfortunately they got nowhere either!

 

They suggested all the things that I had tried and even gave me a break down of the events used. So far though I have found that EnteringQuiescentstateis the best option I can get. The entities updates immediately when the properties are changed, however my application does get told when the user clicks back into the drawing, which is better than nothing. So far I have found it works as per CommandEnded for all other events.

 

I simply wont get away with tell them not to edit via the properties box, so this is the best i can get for now.

 

I have asked ADN to look into a fix for this, along with the fact that the LayLockFadeCtl is not taken into account when you lock/unlock layers from code. Chances are though we are far down their list of priorities as the LayLockFadeCtrl has been an issue since the first release that contained it - 2008!

 

I hope that is of some use to you, let me know if I can help with any pointers.

Valued Mentor
jeff
Posts: 338
Registered: ‎05-12-2009
Message 9 of 15 (309 Views)

Re: Responding to the Properties Palette

03-16-2012 02:24 PM in reply to: Mathew.webber

I have not thought this threw at all or about the different scenarios and probably will not be route to take but to throw the idea out there.

 

If you are depending on on CommandEnded event could you check in Modified handler something like Document.CommandInProgress to see if object is being modified via a command and handle it there?

 

It might require setting a flag for first Modified then send command to stack and reset flag in CommandEnded event.

You can also find your answers @ TheSwamp
Distinguished Contributor
JanetDavidson
Posts: 141
Registered: ‎08-23-2011
Message 10 of 15 (300 Views)

Re: Responding to the Properties Palette

03-16-2012 07:40 PM in reply to: Mathew.webber

Thanks for getting back to me Matt. the bad thing about [EnteringQuiescentstateis] is , it fires everytime user enter the properties window, even though nothing changed. basically everytime ,something is written in command prompt make it fires including entring/existing properties window.

Tony T is the man who  could solve these things which been disappeared for almost a year.

Well what can I say? we are stuck.

Please update if you found a trick .

All the best,

Janet.

 

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.