0

我将 arcobjects 地图事件连接到 vb.net 表单以侦听地图选择更改。这一切正常,但用户在打开表单时偶尔会报告此错误。我看不到任何重现错误的模式,而且它似乎是随机的。

“无法使用已与其底层 RCW 分离的 COM 对象”

它源自我挂钩事件的表单Load()方法。

谁能帮我理解我做错了什么?我正在取消 FormClosing() 事件中的地图选择事件,我认为这是正确的方法。

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
4

2 回答 2

1

您创建和销毁处理程序的方法是有效的。当您的表单打开时更改地图文档时,您可能会收到 RCW COM 异常。由于您使用FocusMap来创建句柄,因此当文档发生更改时, 也将如此FocusMap,这意味着您需要为新的地图文档重新创建处理程序。

于 2017-07-11T17:20:41.723 回答
0

好的,所以我想我已经通过使用 ActiveViewChanged 事件解决了这个问题。我没有在每个表单加载或新文档事件上重新挂钩事件,而是尝试侦听何时触发 ActiveViewChanged 事件并每次重新挂钩 SelectionChanged 事件。事实证明,每次打开新文档时都会触发多次(不知道为什么)。无论如何,问题似乎已经消失了。这是一些示例代码:

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
于 2017-07-21T14:27:06.117 回答