Search code examples
vb.neteventscomarcobjectsrcw

"COM object that has been separated from its underlying RCW cannot be used" error related to vb.net form event


I'm hooking an arcobjects map event to a vb.net form to listen for map selection changes. This all works fine but users are reporting this error occassionally when opening the form. I can't see any pattern to reproduce the error and it seems to be random.

"COM object that has been separated from its underlying RCW cannot be used"

It originates from the form Load() method where I am hooking the event.

Can anyone help me understand what I've done wrong? I'm unhooking the map selection event in the FormClosing() event which I think is the correct approach.

Public Class MyForm

    Private _activeViewEvents As IActiveViewEvents_Event

    Private Sub FormLoad(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        _activeViewEvents = TryCast(pMxDoc.ActiveView.FocusMap, IActiveViewEvents_Event)
        AddHandler _activeViewEvents.SelectionChanged, AddressOf SelectionChanged    
    End Sub

    Private Sub SelectionChanged
        'do something when selection is changed
    End Sub

    Private Sub FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        RemoveHandler _activeViewEvents.SelectionChanged, AddressOf SelectionChanged
    End Sub

End Class

Solution

  • Ok so I think i've resolved this via use of the ActiveViewChanged event. Instead of rehooking the event on each form load or new document event, I tried listening for when the ActiveViewChanged event was fired and rehooking the SelectionChanged event each time. Turns out this is fired more than once each time a new document is opened (not sure why). Anyway, problem seems to have gone. Here's some example code:

    Public Class MyForm
    
    Private _activeViewEvents As IActiveViewEvents_Event
    Private _docEvents As IDocumentEvents_Event
    
    Private Sub FormLoad(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler _docEvents.ActiveViewChanged, AddressOf ActiveViewChanged
    End Sub
    
    Private Sub ActiveViewChanged()
        Dim maps = pMxDoc.Maps
        For i = 0 to maps.Count - 1 'remove handlers from all maps
            RemoveActiveViewEvents(maps.Item(i))
        Next
        SetupActiveViewEvent(pMxDoc.ActiveView.FocusMap) 'only add handler to active map
    End Sub
    
    Private Sub RemoveActiveViewEvents(map As IMap)
        _activeViewEvents = CType(map, IActiveViewEvents_Event)
        RemoveHandler _activeViewEvents.SelectionChanged, AddressOf SelectionChanged
    End Sub
    
    Private Sub SetupActiveViewEvents(map As IMap)
        _activeViewEvents = CType(map, IActiveViewEvents_Event)
        AddHandler _activeViewEvents.SelectionChanged, AddressOf SelectionChanged
    End Sub
    
    Private Sub SelectionChanged
        'do something when selection is changed
    End Sub
    
    End Class