首页 > 解决方案 > 在主窗体关闭时关闭多个父窗体

问题描述

我有一个未使用应用程序框架的 vb.net 应用程序:

在此处输入图像描述

此应用程序具有以下主要功能:

Imports System.Threading

Module Main

    Private _sharedThing As SharedThing = New SharedThing()
    Private _appRunner As AppRunner = New AppRunner()
    Private _firstForm As Form
    Private _secondForm As SecondParent
    Public Event CloseApplication()

    Sub StartFirstParent()

        Dim firstForm = New Form1(_sharedThing, _appRunner, _secondForm)
        Application.Run(firstForm)

    End Sub


    Sub Main()

        Dim mainForm As New Form1(_sharedThing, _appRunner, _secondForm)
        Application.Run(mainForm)
        Application.Exit()
    End Sub


End Module

如您所见,我在一个表单上调用 Application.Run,​​并使用一个按钮创建另一个表单,即 SecondParent 表单。因此,我有两个父表格。这是Form1的代码:

Imports System.Threading

Public Class Form1

    Private _sharedThing As SharedThing
    Private _appRunner As AppRunner
    Public Event CloseApplication()
    Private _otherParentForm As SecondParent

    Public Sub New(aSharedThing As SharedThing, ByRef appRunner As AppRunner, otherParentForm As SecondParent)

        _otherParentForm = otherParentForm
        _sharedThing = aSharedThing
        _appRunner = appRunner
        _otherParentForm = otherParentForm

        Me.IsMdiContainer = True
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.

    End Sub

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

        _sharedThing.SetString("First Parent: Form1")

    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        _sharedThing.ShowString()

    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        Me.Close()

    End Sub


    Private Sub CreateSecondParent(sender As Object, e As EventArgs) Handles Button4.Click

        Dim SecondThread As New Thread(New ThreadStart(AddressOf StartSecondParent))
        SecondThread.Start()

    End Sub


    Sub StartSecondParent()

        Dim secondForm As Form = New SecondParent(_sharedThing, Me)
        Application.Run(secondForm)

    End Sub


End Class

这是 SecondParent 的构造函数:

Public Class SecondParent


    Private _sharedThing As SharedThing

    Private WithEvents _myParent As Form1



    Public Sub New(ByRef aSharedThing As SharedThing, ByRef myParentForm As Form1)

        _myParent = myParentForm
        _sharedThing = aSharedThing

        Me.IsMdiContainer = True

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub

我想不出在退出 Form1 表单时关闭 SecondParent 表单的方法。

如您所见,我主要调用 Application.Exit()。我想避免这种情况,或了解其后果。请理解,几乎所有代码的布局方式都是我必须忍受的约束,因此任何完全改变结构的建议都是无益的。如果不清楚,如果我不使用 Application.Exit(),则创建的新表单不会在主表单关闭时关闭。

我不能使用事件处理程序,因为我收到错误。假设我把它放在 SecondParent 的代码中:

Public Sub KillSwitch_Sensor() Handles _myParent.CloseApplication
    Me.Close()
End Sub

我收到一条错误消息:

 : 'Cross-thread operation not valid: Control 'SecondParent' accessed
 from a thread other than the thread it was created on.'

标签: .netvb.netformsexitmdi

解决方案


您的问题在于变量范围以及其他问题(此处不是代码审查)。快速而肮脏的修复,在 Form1 上添加一个方法,Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing然后在该表单关闭时执行您需要执行的操作...

例如:遍历打开的表单并关闭您想要的表单。我是否推荐这个,当然不是,但在这一点上它是一个选项,无需重构您拥有的大部分代码。

您可能面临的一个问题是Cross-thread operation异常,因为您可能试图从另一个线程关闭表单。如果发生这种情况,您将需要调用控件并且它应该可以工作。


推荐阅读