I have a group of classes that essentially implement the Model View Controller pattern. The view is a custom control contained in a PaletteSet. The Model is a class that wraps the ObjectID of a given block. I've used these classes to create a replacement for the Properties tool in AutoCAD (2011). Basically the UI can be used to edit the properties of a Dynamic Block. But I apply my own rules and behaviors to the UI.
I had no problems until I added support for the View to be updated when the block is modified (say by dragging to increase a length property). To do this I handle the Modified event of the block. After the block is modified, some rules are evaluated. If the rules result in changes to the block's properties, these changes are applied. This last part is where I'm having trouble.
When the "Rule Evaluation" code is invoked because of changes to the view (WinForms Controls), I am able to update the block's Properties using the following code without issue (Sorry, it's VB.NET. My employers choice, not mine):
Public Shared Function SetParameter(ByVal BlockID As ObjectId, ByVal ParameterName As String, ByVal Value As Double) As Boolean
Using dl As DocumentLock = Application.DocumentManager.MdiActiveDocument.Lock
Using myTrans As Transaction = BlockID.Database.TransactionManager.StartTransacti
Dim myBRef As BlockReference = BlockID.GetObject(OpenMode.ForWrite)
For Each myDynamProp As DynamicBlockReferenceProperty In myBRef.DynamicBlockReferencePropertyCollection
If myDynamProp.PropertyName.Equals(ParameterName, StringComparison.OrdinalIgnoreCase) Then
myDynamProp.Value = Value
However, when this same code is invoked as a result of the BlockReference Modified event, AutoCAD completely crashes the momment the transaction.Commit() method is called. I've attempted to catch the exception causing the crash and role back the transaction, but AutoCAD simply exits and displays the error (Error handler re-entered. Exiting now.) and no exception is caught. Note that I do not use the BlockReference instance passed to the Modified event handler. Instead I store an ObjectID instance elsewhere which is consistently used to read/write the block.
Is there something I must do before commiting a transaction when using the Modified event of BlockReference? I checked, and the same "Main Thread" is executing whether the code is invoked from a UI event or the Modified event. I tried calling the Close method, which is attributed as Obsolete, on the BlockReference object before executing the transaction without any success.
Thanks for any help. I'm a bit new to the AutoCAD API.
Solved! Go to Solution.
To make things clearer and easier to read, I've attached the code for the "Model" class mentioned in the opening post. After the class definition, I've provided the code for one of the methods called to update a block property value. When the transaction.Commit() method is called, AutoCAD crashes as previously described.
>> However, when this same code is invoked as a result of the BlockReference Modified event,
>> AutoCAD completely crashes the momment the transaction.Commit() method is called
Within the event AutoCAD has the blockreference currently open (and locked for it's own modifications), so you can't commit any additional changes while the entity is "in-change" state.
I would do in that case
within the object-modified event
within the eventhandler "got Quiescent"
HTH, - alfred -
Thank you Alfred.
To fix the issue, I added a handler for the Editor.EnteringQuiencentState event. I also added a local boolean variable 'BlockHasModification' that I set to true when the Modified event is raised. In the EnteringQuiencentState event handler, I check the BlockHasModification variable. If it is True, I first set it to false, and then perform further transactions if needed on the given block. So far AutoCAD has stopped crashing. I'm attaching the updated code for anyone that stumbles on this thread.