Hey all! I am writing a program that opens a form when the program is run. I have no problems opening the form or hopping between methods. The problem arises when I get the active civil document (or utilize it) after the form is closed. I know the import Point section is correct because it works fine in a Class Library by itself. So somewhere the form is causing problems. I have tried a multitude of solutions including CommandFlags, activating the window, and focusing the window. (Commented Lines in snippet) Any help would be appreciated! I am probably just being blind. Thanks!
Class 1
Public Class Class1
Public Shared acadDoc As Document
Public Shared civilDoc As CivilDocument
<CommandMethod("MHLBF", CommandFlags.Session)>
Public Sub RunMHLB()
acadDoc = Application.DocumentManager.MdiActiveDocument
civilDoc = CivilApplication.ActiveDocument
//acadDoc.LockDocument()
Dim f As New Form1
f.Show()
End Sub
Public Sub Insertpoint()
//Dim app As AcadApplication = Application.AcadApplication
//app.ActiveDocument.Activate()
//acadDoc.Window.Focus()
Using acCurDb As Database = acadDoc.Database
Using trans As Transaction = acCurDb.TransactionManager.StartTransaction()
Dim pointFileName As String = "C:\Users\jdalton\Desktop\091021_PCV3_ASB_SH.csv"
Dim pointFileFormatName As String = "PNEZD (comma delimited)"
Dim pointFileFormat As PointFileFormat = PointFileFormatCollection.GetPointFileFormats(acCurDb)(pointFileFormatName)
Dim pointGroupId As ObjectId = civilDoc.PointGroups.Add("AddedPoints")
Dim result As UInteger = CogoPointCollection.ImportPoints(pointFileName, pointFileFormat, pointGroupId)
trans.Commit()
End Using
End Using
End Sub
End Class
Form Class
Public Class Form1
Public Sub InsButton_Click(sender As Object, e As EventArgs) Handles InsButton.Click
Close()
Dispose()
Dim callMethod As Class1 = New Class1
callMethod.Insertpoint()
End Sub
End Class
Edit: Upon further inspection, ObjectLeftOnDisk = 'pointGroupIf.ObjectLeftOnDisk' threw an exception of type 'System.AccessViolationException' I also get this error. So maybe my context is screwed up or I am doing something horribly wrong
Edit 2: Continuing my investigation, if I click the app just before it grabs the active document and starts the transaction, it works. Still trying to make the app become the active window. Any help would be appreciated!
Attached is the Error in Visual Studio and the Error in CAD
It looks like you have not mastered AutoCAD .NET API basics yet. Namely:
1. You do not show a UI (Win Form, in your case) by calling Form.Show()/ShowDialog() in AutoCAD. You need to use
Autodesk.AutoCAD.ApplicationServices.Application.ShowModal[Modeless]Dialog[Window]() method.
2. Your UI/Form is shown as modeless dialog (floating UI). IN this case, if the UI triggers an action to modify a drawing database, the document must be locked with Document.Lock() method, or you let the UI action calls Document.SendStringToExecute() method to call a Command method (this is recommended approach when modeless UI is used.
3. Finally, you need think hard as to using modal UI or modeless UI. The latter poses quite some challenge in AutoCAD programming if the data presented on the modeless UI is drawing specific because user could switch to another drawing while the UI is showing.
Norman Yuan
You can either go to Autodesk's online developer guide, such as this:
https://help.autodesk.com/view/OARX/2022/ENU/
or download AutoCAD ObjectARX SDK, which comes with .NET code samples (well, it only touches very limited topics).
In terms of doing UI in AutoCAD plugin, @_gile has a very good tutorial for one to get started:
https://gilecad.azurewebsites.net/UserInterfaces.aspx
Other than those, this forum is obviously a good place to learn/discuss .NET API topics.
Norman Yuan
@joshmcdalton First off please direct Civil3D customization questions to the C3D Customization forum. Second, I sure wish you were using c# instead of VB as there are far more sample code snips available. Now, as to your specific issue in addition to what Norman mentioned, in one instance of Class1 you are setting the acad document and civil document and calling the Form. Then in the form button you close/dispose the form and create a new instance of Class1 so when you call the Insertpoint() it has no reference to the previously set documents.
Have you considered doing something like this?
......
Dim f As New Form1
If Application.ShowModalDialog(f).Status == DialogResult.OK
Then InsertPoint()
End Sub
not sure if that is the correct format for VB as I don't usually use it, but should be close.
Or, if you are wanting the InsertPoint to be done in a different drawing than the one which called the command, I would suggest using a side database instead. If this is the case, please post over in the C3D Customization forum and I can show you an example of this, albeit in c#.
Can't find what you're looking for? Ask the community or share your knowledge.