Search code examples
vb.netautocad-plugin

datagrid error: Exception has been thrown by the target of an invocation


I'm working on an AutoCAD plug-in. The following three functions are from a course by AutoCAD, written by Jerry Winters. I'm using these functions to obtain the data I need and pass it into a data grid.

    Function SelectAllBlocks(dbIn As Database) As ObjectIdCollection
    Dim retIDs As New ObjectIdCollection
    Using myTrans As Transaction = dbIn.TransactionManager.StartTransaction
        Dim myBT As BlockTable = dbIn.BlockTableId.GetObject(OpenMode.ForRead)
        For Each btrID As ObjectId In myBT
            Dim myBTR As BlockTableRecord = btrID.GetObject(OpenMode.ForRead)
            For Each BRefID As ObjectId In myBTR.GetBlockReferenceIds(True, False)
                retIDs.Add(BRefID)
            Next
        Next
    End Using
    Return retIDs
End Function
Function GetBlockProperties(ObjID As ObjectId) As Dictionary(Of String, Object)
    Dim myD As New Dictionary(Of String, Object)
    Using myTrans As Transaction =
    ObjID.Database.TransactionManager.StartTransaction
        Dim myEnt As BlockReference =
        ObjID.GetObject(OpenMode.ForRead)
        For Each myPInfo As Reflection.PropertyInfo In GetType(BlockReference).GetProperties
            myD.Add(myPInfo.Name, myPInfo.GetValue(myEnt))
        Next
    End Using
    Return myD
End Function
Function GetBTRProperties(ObjID As ObjectId) As Dictionary(Of String, Object)
    Dim myD As New Dictionary(Of String, Object)
    Using myTrans As Transaction =
    ObjID.Database.TransactionManager.StartTransaction
        Dim myEnt As BlockTableRecord =
        ObjID.GetObject(OpenMode.ForRead)
        For Each myPInfo As System.Reflection.PropertyInfo In GetType(BlockTableRecord).GetProperties
            myD.Add(myPInfo.Name, myPInfo.GetValue(myEnt))
        Next
    End Using
    Return myD
End Function

My code, which is an attempt to rewrite some of the material from the course for my own needs, loads some information into the data grid but throws an "Exception has been thrown by the target of an invocation" error.

    Private Sub cmdBlocks_Click(sender As Object, e As EventArgs) Handles cmdBlocks.Click
    Dim tbl As New System.Data.DataTable
    ' Create four typed columns in the DataTable.
    tbl.Columns.Add("User name", GetType(String))
    tbl.Columns.Add("Full name", GetType(String))
    tbl.Columns.Add("Time", GetType(String))
    tbl.Columns.Add("name", GetType(String))
    tbl.Columns.Add("Block handle", GetType(String))
    tbl.Columns.Add("Block name", GetType(String))
    tbl.Columns.Add("Location X", GetType(String))
    tbl.Columns.Add("Location Y", GetType(String))
    tbl.Columns.Add("Location Z", GetType(String))
    dgvBlocks.DataSource = tbl
    Dim myDB As Database = HostApplicationServices.WorkingDatabase,
        myIDs As ObjectIdCollection = SelectAllBlocks(myDB)
    Using myTrans As Transaction = myDB.TransactionManager.StartTransaction
        For Each myBID As ObjectId In myIDs
            Dim blockProps As Dictionary(Of String, Object) = GetBlockProperties(myBID)
            Dim blockProps2 As Dictionary(Of String, Object) = GetBTRProperties(blockProps("DynamicBlockTableRecord"))
            Dim blockAtts As Dictionary(Of String, Dictionary(Of String, String)) = GetBlockAttributes(myBID)
            Dim username As String = My.Computer.Name,
                filename As String = HostApplicationServices.WorkingDatabase.Filename,
                time As String = DateTime.UtcNow,
                Name As String = blockProps2("Name"),
                BlockHandle As String = blockProps("Handle").ToString,
                BlockName As String = blockProps("BlockName").ToString,
                location As Point3d = blockProps("Position"),
                locX As String = location.X.ToString,
                locY As String = location.Y.ToString,
                locZ As String = location.Z.ToString
            tbl.Rows.Add(username, filename, time, Name, BlockHandle, BlockName, locX, locY, locZ)
        Next
        myTrans.Abort()
    End Using
End Sub

Solution

  • The "eLockViolation" exception usually happens when you try modify the database from a modeless form or palette (which is also modeless).

    Here is a way to lock it:

    Using docLock As DocumentLock = Application.DocumentManager.MdiActiveDocument.LockDocument()
        ' do your code here...
    End Using
    

    Usually you call it once, meaning one lock per action to change database, even if you have several transactions, but you might consider one lock per transaction to make it easier to implement (although at higher performance cost).