I cannot seem to set the MdiActiveDocument synchronously.
I have code inside a <CommandMethod> that creates a drawing and then writes any error information to the command line. Since this is started in one document, if a fatal error occurs and the drawing does not get created, that message goes to the original document's command line.
In the case where a drawing gets created with errors (say partial success), I would like the errors to appear in the new drawing (new active document's) command line.
The behavior when setting Core.Application.DocumentManager.MdiActiveDocument is peculiar. The application can hang for a long time if you do not click anything. If you click the document (from the taskbar or clicking on the window), it breaks out of the hang and continues to execute, but the active document is not changed. The MdiActiveDocument still points to the original document. You can also see that it does not change because doc.IsActive = False. This state could be because when you clicked, you really did make the original document active (again? still?). To break the hang, I think the click has to be on the original document.
On an example like http://www.theswamp.org/index.php?topic=44476.msg497357#msg497357 there is no action taken after MdiActiveDocument is set, so I assume that it is actually set when the command is completed, not synchronously. I am not absolutely certain of this, though.
<CommandMethod("AUTODRAWPN")> _
Public Sub DrawPartNumber()
Dim ed As Editor = Core.Application.DocumentManager.MdiActiveDocument.Editor
If IsNothing(drwr) Then
Try
InitalizeAutodraw()
Catch ex As System.Exception
'exit quietly if it is cancelled by the user
'print the error if an exception happened
If ex.GetType <> GetType(OperationCanceledException) Then
ed.WriteMessage("Error: " & ex.Message)
End If
Exit Sub
End Try
End If
Try
Dim pr As PromptResult = ed.GetString("Part number to draw: ")
If pr.Status <> PromptStatus.OK Then Exit Sub
Dim doc As Document = drwr.CreateByPartNumber(pr.StringResult)
'Core.Application.DocumentManager.MdiActiveDocument = doc 'does not work
If drwr.Errors.Count > 0 Then
ed = Core.Application.DocumentManager.MdiActiveDocument.Editor
ed.WriteMessage("Autodraw Error(s):" & vbCrLf & String.Join(vbCrLf, drwr.Errors))
ed.WriteMessage(vbCrLf)
End If
Catch ex As System.Exception
ed.WriteMessage("Error: " & ex.Message)
End Try
End Sub
Is there a way to set the MDIActiveDocument? Should it be hanging like this? Should I be looking at an altogether different way to handle this?
Trying to use doc.Editor without setting the active causes a eNotApplicable error, so that is not a way out.
I am using AutoCAD 2013. The following link implies that this could be a 2013 specific problem, but I do not know that for sure.
http://forums.autodesk.com/t5/NET/MDIActiveDocument-and-DocumentActivated/td-p/3629886
Thanks for whatever you guys can tell me!!
Solved! Go to Solution.
I got it !!
The key was to declare my function as
<CommandMethod("AUTODRAWPN", CommandFlags.Session)>
rather than
<CommandMethod("AUTODRAWPN")>
This indicates that that the context is the entire AutoCAD session rather than running in only a specific document. Now when I set MdiActiveDocument it takes and I can send my results to the correct Editor.
In fact, if I want, I don't even have to set the active document, since I now can write to doc.Editor without getting an eNotApplicable error. This attribute definately opens up more cross-document abilities.
This workaround is going to solve it:
void SetActiveDocumentAndDoSomethingWithItWhenUpdated()
{
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentActivated += DrawingActivated;
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument = myDocument;
}
private void DrawingActivated(object sender, EventArgs e)
{
//here Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument == myDocument. Do anything you want with it here
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.DocumentActivated -= DrawingActivated;
}
You basically subscribe to the event of document changes, and only when the event comes later on (before Application.Idle it will come), only then you MdiActiveDocument has been changed