Hi,
I have difficulties to set MDIActiveDocument. I read many post but any is working. I create a sample program. That program open a drawing try to set it current and set a layout current. The drawing open but the MDIACTIVEDOCUMENT is always the drawing I run the program. I'm working with VS2010 and AutoCAD 2012.
Here's my class:
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports System.Windows.Forms
Imports System.IO
Public Class TestDocSwitch
<CommandMethod("TestDocSwitch", CommandFlags.Session)> _
Public Sub TestDocSwitch()
Dim DWGNameToOpen As String = "D:\LOGESDES\3177\H90930\3177-90930-001-01-E-LR-1.DWG"
Dim LayoutName As String = "Model"
OpenDrawing(DWGNameToOpen, LayoutName)
End Sub
Public Sub OpenDrawing(DrawingName As String, Optional LayoutName As String = "")
Dim acDocMgr As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
Dim acDoc As Autodesk.AutoCAD.ApplicationServices.Document = Nothing
If (File.Exists(DrawingName)) Then
acDoc = acDocMgr.Open(DrawingName, False)
Else
acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " & DrawingName & " does not exist.")
End If
acDocMgr.MdiActiveDocument = acDoc
If LayoutName <> "" Then
SetCurrentLayoutTab(LayoutName)
End If
End Sub
Public Sub SetCurrentLayoutTab(ByVal LayoutName As String)
Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
MessageBox.Show(acDoc.Name)
Dim acCurDb As Database = acDoc.Database
Using doclock As DocumentLock = acDoc.LockDocument
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
Try
Dim acLayoutMgr As LayoutManager
acLayoutMgr = LayoutManager.Current
acLayoutMgr.CurrentLayout = LayoutName
acTrans.Commit()
Catch ex As Autodesk.AutoCAD.Runtime.Exception
Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message & vbCr & ex.StackTrace)
acTrans.Abort()
End Try
End Using
End Using
End Sub
End Class
In my complete program I need to obtain information about the current layout but it doesn't work because the active drawing is not the drawing I open.
Need help!
Regards,
André
Solved! Go to Solution.
Solved by andre_adc-dao. Go to Solution.
Thank you,
I read your post and it is not a problem only with 2013.
Regards,
André
Tested yor code in 2014
Solution (on my end):
to avoid this error
//Error 1 ... 'TestDocSwitch': member names cannot be the same as their enclosing type //
Rename
Public Sub TestDocSwitch on
Public Sub TestDocSwitchCommand
Also I've added refrerence to accoremgd.dll (copy local=false)
Let us know if this work on your release
Thank you for your reply Hallex,
It is not necessary to rename the command. The name can be the same (I use it all the time). The command is running, the only problem is Mdiactivedocument is not change. You can notice the MessageBox in the SetCurrentLayoutTab sub, it display the name of the first drawing, not the last drawing open.
Also the reference to accoremgd.dll is required only from 2013 release, not 2012.
Regards,
André
Thank you Hallex,
It doesn't change anything but I found my problem. When you debug with VS2010 and AutoCAD 2012 sometimes you have to set NEXTFIBERWORLD variable to 0. I don't know why exactly but it works. Usually I debug my app with this variable set to 0. I changed it to 1 (normal mode) and you have to restart AutoCAD to apply the changes. Voilà! my messagebox show the last open document name (not the first one). I will try it in my main application to be sure it is working well.
Maybe with AutoCAD 2013/2014 you don't have to set this variable. It was not necessary when I develop application for AutoCAD 2010 (VS2008).
Best regards,
André
I confirm, set NEXTFIBERWORLD to 1 (default value) solve my problem in my main application.
Regards,
André
Or without nextfiberword, try this code, tested from A2010 to 2014
it works everywhere:
Public Class TestDocSwitch Public is_template As Boolean = True <CommandMethod("ts", CommandFlags.Session)> _ Public Sub testNewDocOpen() Dim docs As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager Dim doc As Document = docs.MdiActiveDocument Dim ed As Editor = Nothing ''System.Windows.Forms.MessageBox.Show(Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Name) ' possible using examples: ' is_template = true; ' OpenDocCallback("acad.dwt");// <-- or acadiso.dwt ' Or is_template = False OpenDocCallback("C:\Test\WorkingDrawing.dwg") ' <-- your file name here docs.MdiActiveDocument = docs.MdiActiveDocument Dim newdoc As Document = docs.MdiActiveDocument ed = newdoc.Editor Using doclock As DocumentLock = newdoc.LockDocument() docs.MdiActiveDocument = newdoc Dim newdb As Database = HostApplicationServices.WorkingDatabase Using tr As Transaction = newdb.TransactionManager.StartTransaction() Dim lmr As LayoutManager = LayoutManager.Current Try Dim layout As Layout = Nothing Try layout = DirectCast(tr.GetObject(lmr.GetLayoutId("Blocks"), OpenMode.ForRead), Layout) ' <-- your layout name here Catch exl As Autodesk.AutoCAD.Runtime.Exception ed.WriteMessage("Error on swith to Layout: {0}" & vbLf & "{1}" & vbLf, "Blocks", exl.Message) End Try LayoutManager.Current.CurrentLayout = layout.LayoutName tr.Commit() Catch ex As Autodesk.AutoCAD.Runtime.Exception ed.WriteMessage((vbLf + ex.Message & vbLf) + ex.StackTrace & vbLf) Finally ed.WriteMessage(vbLf + "I hope you're satisfied with the result." + vbLf) End Try End Using End Using End Sub Public Sub OpenDocCallback(Data As Object) ' Open the document here, whose name was passed in ' the Data parameter Dim docs As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager If is_template Then docs.Add(Data.ToString()) Else docs.Open(Data.ToString(), False, "") ' documents is already open and activated, pass your utility here: 'Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.RunCommand("my cool command, etc");//2014 End If End Sub End Class
Change a drawing name and layout name in the code,
Cheers
Thank you Hallex for your code.
It is working well but it does work differently depending of NEXTFIBERWORLD setting. When set to 0, the MIDACTIVEDOCUMENT is not set to the new open document. In your code, you use "newdb" pointing to the database of the just open drawing to get information about layouts.
...
MessageBox.Show(docs.MdiActiveDocument.Name)
Dim newdb As Database = HostApplicationServices.WorkingDatabase
MessageBox.Show(newdb.Filename)
...
NEXTFIBERWORLD=1: The message boxes displays the same drawing name
NEXTFIBERWORLD=0: The first message box displays "Drawing1" (or the name of the current drawing).
So each time I have to get information about this drawing I have to set a database variable, not use the current one. This is a litte bit annoying because I have to pay attention at this each time I want to access current document information. But it is a good workaround.
Thanks a lot!
André
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
Can't find what you're looking for? Ask the community or share your knowledge.