"COM object that has been separated from its underlying RCW cannot be used" 与 vb.net 表单事件相关的错误
"COM object that has been separated from its underlying RCW cannot be used" error related to vb.net form event
我正在将 arcobjects 地图事件挂接到 vb.net 表单以监听地图选择更改。这一切都很好,但用户在打开表单时偶尔会报告此错误。我看不到任何模式来重现错误,它似乎是随机的。
"COM object that has been separated from its underlying RCW cannot be used"
它源自我挂接事件的 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
您用来创建和销毁处理程序的方法是有效的。如果在表单打开时地图文档发生更改,您可能会收到 RCW COM 异常。由于您正在使用 FocusMap
创建句柄,当文档更改时,FocusMap
也会更改,这意味着您需要为新地图文档重新创建句柄。
好的,我想我已经通过使用 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
我正在将 arcobjects 地图事件挂接到 vb.net 表单以监听地图选择更改。这一切都很好,但用户在打开表单时偶尔会报告此错误。我看不到任何模式来重现错误,它似乎是随机的。
"COM object that has been separated from its underlying RCW cannot be used"
它源自我挂接事件的 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
您用来创建和销毁处理程序的方法是有效的。如果在表单打开时地图文档发生更改,您可能会收到 RCW COM 异常。由于您正在使用 FocusMap
创建句柄,当文档更改时,FocusMap
也会更改,这意味着您需要为新地图文档重新创建句柄。
好的,我想我已经通过使用 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