2
votes

I have an vb.net application for which I am not using the application framework:

enter image description here

This application has the following main:

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

As you can see, I call Application.Run on one form and, using a button, create another form, the SecondParent form. Thus, I have two parent forms. Here is the code for 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

Here is the constructor for 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

I cannot figure out a way to close the SecondParent form upon the exit of the Form1 form.

As you can see, in the main, I call Application.Exit(). I want to avoid this, or understand its consequences. Please understand that almost all of the way the code is laid out is a constraint I have to live with, so any suggestions of completely changing the structure are unhelpful. If it isn't clear, if I don't use Application.Exit(), the new forms that are created do not close upon the main form being closed.

I can't use event handlers because I get an error. Suppose I put this in my code in SecondParent:

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

I get an error saying that:

 : 'Cross-thread operation not valid: Control 'SecondParent' accessed
 from a thread other than the thread it was created on.'
1
Your problem is with variable scopes along with other issues(not code review) ... Quick and dirty, add a method on Form1 for Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing then do what you need to do when that form is closing... For ex: loop through the open forms and close the ones you want... Do I recommend this, surely no... - zaggler
@Çöđěxěŕ, that doesn't work. Form.close causes the same exception as listed at the bottom of the post "Cross-thread operation not valid" - user442920
You need to invoke that control then... - zaggler
@Çöđěxěŕ Ok, I invoked the form.close and it works! Thank you! Feel free to answer this and I will award it. - user442920

1 Answers

1
votes

Your problem is with variable scopes along with other issues (not code review here). A quick and dirty fix, add a method on Form1 for Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing then do what you need to do when that form is closing...

For example: loop through the open forms and close the ones you want. Do I recommend this, surely no, but it's an option at this point without refactoring most of the code you have.

One issue you may face is a Cross-thread operation exception as you maybe trying to close a form from another thread. If this happens, you would need to invoke the control and it should work.