0

我按照此处的 Microsoft 大师 Andrew Whitechapel 的指示为 Microsoft Access 创建了 VSTO 插件,并且运行良好。但是插件有一个 CustomTaskPane,当 Access 关闭时我遇到了问题。

如果在 Access 关闭时 CustomTaskPane 打开,则插件应保存 CustomTaskPane 控件的属性。如果将此代码放在 中ThisAddIn_Shutdown(),我会收到以下错误:

System.ObjectDisposedException: Cannot access a disposed object.
  at Microsoft.Office.Tools.CustomTaskPane.get_Control()
  at MyAddin.ThisAddIn.ThisAddIn_Shutdown(Object sender, EventArgs e) in C:\...\ThisAddIn.vb:line nn

我不确定这是 CustomTaskPanes 或 Windows 窗体控件的正常操作,还是因为 VSTO 不是为 Access 设计的。我想知道是否会发生这种情况,因为 Access 没有应用程序级别的事件,例如 Access.Application."OnClose",其他 VSTO 批准的应用程序(例如 Excel 和 Word)也是如此。

经过一些实验后,我找到了一种解决方法,即使用HandleDestroyed控件的事件,该事件发生在 之前Dispose(),因此控件属性仍然可用。这有效:

Private Sub TextBox1_HandleDestroyed(ByVal sender As System.Object, ByVal e As System.EventArgs) _
            Handles TextBox1.HandleDestroyed
    MsgBox(TextBox1.Text)
End Sub

有没有更好的办法..?变通办法让我很紧张。

4

1 回答 1

0

在跟踪事件的轨迹时,我意识到了我自己问题的答案。重点是中的Dispose方法usercontrol.designer.vb。但是,众所周知,设计器生成的代码不应直接修改,因为在设计器中对用户控件进行任何后续更改后,它可以并且将被刷新和覆盖。

除了...该规则并不完全适用于某些方法,例如Dispose. 看这里。如果程序员随后将这些方法从usercontrol.designer.vbto移动usercontrol.vb,设计者将遵从它们 inusercontrol.vb并且不会在 in 中重新生成它们usercontrol.designer.vb

于是,我们得到了答案:将Dispose方法移到usercontrol.vb,移除System.Diagnostics.DebuggerNonUserCode属性,然后添加必要的代码来保存控件属性,如下所示:

Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    Try
        SaveUserControlProperties()    <--- additional code added here
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
        End If
    Finally
        MyBase.Dispose(disposing)
    End Try
End Sub
于 2020-01-12T02:39:29.147 回答