VB.NET 2019从其他窗体打开窗体

VB.NET 2019从其他窗体打开窗体,vb.net,winforms,singleton,Vb.net,Winforms,Singleton,我知道这似乎是一个相当常见的话题,应该在以前的帖子中解决。但我所经历的似乎仍然没有在线解决方案: 我有一个名为ExpenseEntry的表单,其中有一个子过程名为Public sub-OpenVoucher。 我想从另一个表单调用此sub,我使用以下代码: Dim ExpForm As New ExpenseEntry ExpForm.Show() ExpForm.OpenVoucher() 虽然这很好,但问题是每次我单击按钮时,都会启动一个新

我知道这似乎是一个相当常见的话题,应该在以前的帖子中解决。但我所经历的似乎仍然没有在线解决方案: 我有一个名为
ExpenseEntry
的表单,其中有一个子过程名为
Public sub-OpenVoucher
。 我想从另一个表单调用此sub,我使用以下代码:

        Dim ExpForm As New ExpenseEntry
         ExpForm.Show()
        ExpForm.OpenVoucher()
虽然这很好,但问题是每次我单击按钮时,都会启动一个新的
ExpenseEntry
窗口。根据我如何设计应用程序,重复窗口是不允许的,一次只能有一个窗口可用。 我尝试了各种方法来限制多个表单,例如使用变量来控制表单,但这会导致其他问题。 如果我使用
Application.OpenForms
,但仍然无法解决问题。 在这方面,我先前曾在以下链接中提出疑问:

我使用的是VB.NET 2019,它不允许启动表单的默认实例,如
form.Show
。我知道这是一种不好的做法,但在VB.NET 2017之前,使用它更容易管理


现在,通过创建一个表单变量并启动它来创建一个无限循环,在这个循环中,我不能让一个表单的一个实例在一个线程上运行。

真正简单的处理方法是使用表单类型的默认实例。在VB中,自2005年以来,每个表单类型都有一个默认实例,您可以通过类型名访问该实例。更多信息。在您的情况下,您可以执行以下操作:

”如果表单尚未显示,则显示该表单。
ExpenseEntry.Show()
'如果表单已显示,则激活该表单。
ExpenseEntry.Activate()
“去做吧。
ExpenseEntry.OpenVouncher()
也就是说,默认实例有点不可靠。在某些情况下,它们确实允许初学者从项目中的任何位置访问表单,但它们也有可能导致问题的限制。但最重要的是,它们通过将表单与其他类型区别对待,有助于阻止您学习正确的OOP。如果希望以适当的开发人员的方式执行此操作,则只需声明一个变量以引用表单的当前实例:

Private ExpenseEntry作为ExpenseEntry的对话
使用表单时,只需检查该变量是否引用了可用实例,如果引用了,则使用该变量,否则创建一个新实例:

如果expenseEntryDialogue为Nothing或Else expenseEntryDialogue.IsDisposed,则
expenseEntryDialogue=新的ExpenseEntry
如果结束
expenseEntryDialogue.Show()
expenseEntryDialogue.Activate()
expenseEntryDialogue.OpenVoucher()
第三种选择是实现您自己的singleton,即只能有一个实例的类型。在VB中,您可能不会这样做,因为默认实例基本上是一个特定于线程的单例,并且更自动地执行,但是,如果您愿意,您可以这样做:

公共类费用录入
私有共享\u实例作为ExpenseEntry
'类型的唯一实例。
作为ExpenseEntry的公共共享只读属性实例
得到
如果_instance为Nothing或lse _instance.IsDisposed,则
_实例=新支出项目
如果结束
返回_实例
结束
端属性
'构造函数是私有的,以防止外部实例化。
私人分新
'设计器需要此调用。
初始化组件()
'在InitializeComponent()调用之后添加任何初始化。
端接头
末级
然后这个:

ExpenseEntry.Instance.Show()
ExpenseEntry.Instance.Activate()
ExpenseEntry.Instance.OpenVoucher()

完全正确,但我在VB.NET 2019中找不到
表单.Show
选项。找不到任何内容。您键入表单类的名称,键入一个点,然后键入“show”。亲爱的@jmcilhinney非常感谢您解决了这个问题。在我在类级别声明变量之后,您显示的第二个选项工作得非常好。但是,我也尝试了
ExpenseEntry.Show
方法,但该方法在下方弹出一条红线,错误显示为
对非共享成员的引用需要对象引用。有空的时候请看一看。项目也无法使用该行进行编译。@KhalidKagzi将类成员方法定义为
Shared
或创建如下实例:
Dim x作为新的MyClass
,并通过
x.method()
访问该方法。根据OOP规则,您不能直接访问该方法。