关闭和重新打开声明为 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)
这解决了问题中提出的难题。
我的问题与 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)
这解决了问题中提出的难题。