0

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
Courlu
  • 106
  • 2
  • 8

2 Answers2

1

The approach you are taking to creating and destroying your handlers are valid. You can receive a RCW COM Exception when the map document is changed while your form is open. Since you are using the FocusMap to create the handles, when the document is changed, so is the FocusMap, which means you need to re-create your handlers for the new map document.

  • I am already taking this approach but unfortunately the problem persists. My form is also hooked to document events so is never left open when the document is changed. Whenever the map doc changes the user must reload the form, so FormLoad() is always re-creating the handlers for the new document. I suspected it was related to changing map docs however so i'll look a bit deeper into it. – Courlu Jul 12 '17 at 13:16
  • Any chance that you are disposing of a resource using `Marshal` or `ComReleaser`? – Kyle Baesler Jul 12 '17 at 17:03
  • No, I'm only ever disposing of search cursors but nothing related to this form or event. – Courlu Jul 13 '17 at 10:58
  • Fixed now by listening to ActiveViewChanged event. Solution posted. – Courlu Jul 21 '17 at 14:27
0

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
Courlu
  • 106
  • 2
  • 8