关闭和重新打开声明为 Public 的表单的正确方法是什么?

What Is the Correct Way to Close and Reopen a Form Declared as Public?

我的问题与 Microsoft Excel 的 COM 加载项有关。用例如下: 1. 用户单击功能区上的加载项按钮。 2. 出现一个表格window。 3. 用户与表单 window 交互并单击“确定”按钮。 4.生成各种报告,同时在表单window上显示进度条。 5. 在过程结束时,表单 window 关闭。

该流程在第一个 运行 上按设计运行,但在表单 window 关闭后,无法启动新的“会话”。从用户的角度来看,加载项按钮变得无响应。当 运行 从 Visual Studio 处于调试模式时,第二次单击加载项按钮会生成一条错误消息:“无法访问已释放的对象。”

很明显我连接所有东西的方式有问题,但我没能找到关于如何正确连接的简单描述。这是我拥有的:

在 public class 中声明了一些 public (或“全局”变量);表单也在这里声明和实例化:

Public Class GlobalVariables

        Public Shared FormInstance As New MyFormDesign

End Class

将表单声明为 public 对象的原因是能够从各种不同的子程序和函数发送进度值。 GlobalVariables class 由所有需要它的模块导入。

功能区按钮后面是一行代码:

FormInstance.Show()

单击按钮实例化并按预期显示表单。为了简单起见,我们可以忽略大部分代码;只需单击“取消”按钮即可触发该问题。 “取消”按钮背后的代码很简单:

Me.Close()
GC.Collect()

根据上面引用的错误消息,关闭表单后无法再创建新实例。

我真的不明白这里发生了什么,但在我看来 GlobalVariables class,一旦创建,就会持续到 Excel 会话结束.如果这是正确的,这个问题大概可以通过在标准模块中实例化表单来解决。每次用户单击按钮时,加载项不会尝试恢复已处理的表单,而是创建一个新实例。但如果我走那条路,我就不知道如何将进度值从其他潜艇发送回表格。好像是第二十二条军规。

必须有一种方法来 (a) 将表单创建为 public 对象,以及 (b) 每次加载项 运行.正确的?我做错了什么?

这是一段漫长的旅程,但我终于找到了如何构建我的问题中描述的功能。我会 post 在这里回答,因为它可能会在将来帮助其他人。

面临的挑战是将表单声明为 Public 以便在整个项目中都可以访问它,以便子程序和函数可以将进度更新发送回表单。

问题是,当按照我的问题中的描述声明和实例化表单时,每个 Excel 会话只能创建一次。

解决方案是将表单声明为 Public 而不实例化它,然后通过 Public ReadOnly Property.

访问它

首先,将 FormInstance 声明为 public 变量而不实例化它:

Public FormInstance As MyFormDesign

其次,定义一个Public ReadOnly Property。这建立了一种调用表单的方法:

Public ReadOnly Property CallMyForm() As MyFormDesign    
    Get
        Return FormInstance
    End Get
End Property

三、ribbon按钮的Click事件实例化显示形式:

Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click

    FormInstance = New MyFormDesign
    FormInstance.Show()

End Sub

现在每次单击功能区按钮都会创建一个新的表单实例,但仍然可以通过 CallMyForm 访问该表单 属性。

而不是...

FormInstance.BackgroundWorker1.ReportProgress(i)

...我们将使用:

CallMyForm.BackgroundWorker1.ReportProgress(i)

这解决了问题中提出的难题。