Problem opening a new instance of a form after its been closed mdi

VB.net 2005
I am using DevExpress but you can switch out the things shown in my code with a regular button or navbar/menu item there is nothing devexpress specific in this question.  I am using it mostly for its layout manager and look and feel support.

OK I have an MDI application.  What I do is when an navitem is clicked I open up a form this form has a bunch of questions on it, the user answers those questions it is validated the results are added to my record class and  that form is hidden and the next form is opened up with more questions for them to answer, my plan is when they get to the final form (I only have 2 question forms and the main form so far),  I will write the record class to a database.

There are and will be more forms unrelated to this set of AddClient forms but it does not pertain to the question.

Looks kind of like this

FrmMain(addClient link clicked)---> FrmAddClient1 opened in FrmMain, 'next button' clicked---->Frmaddclient1 is hidden and FrmAddClient2 is shown in FrmMain etc.

I have a back button on FrmAddClient2 which hides that form and shows FrmaddClient1 again, there they can edit what they had done before and proceed on if they wish.  

Say the user decides to press the cancel button or close either of the child addClientForms, well then I prompt the user in the closing event to give them a chance to cancel or all data will be lost and the form closes.

The problem is once the form closes I can not open up a new instance of FrmAddClient1 when I click the navbar on the main form.

Can somebody show me why once I close my form I am unable to open another one?

My desire is to only hide the forms as they are going through so that they can use the back button to edit previous data.  However if they close any of the question forms I wish them destroyed so I can open up a new instance.

Hope that makes sense.

William





#### Here is FrmMain (MDI parent form) ######
 
Public Class FrmMain
    Public WithEvents frm1 As frmAddClient1
    Public WithEvents frm2 As FrmAddClient2
 
    Private Sub NavBarItem1_LinkClicked(ByVal sender As System.Object, ByVal e As DevExpress.XtraNavBar.NavBarLinkEventArgs) Handles NavBarItem1.LinkClicked
 
        For Each fChildren As Form In MdiChildren
            If (TypeOf fChildren Is frmAddClient1) Then
                MessageBox.Show("You may only add one client at a time", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
                Return
            End If
        Next
 
        FormHandler("frm1")
 
    End Sub
 
    Public Sub FormHandler(ByVal frmName As String)
        Select Case frmName
            Case "frm1"
                If frm1 Is Nothing Then
                    frm1 = New frmAddClient1
                    frm1.MdiParent = Me
                End If
 
                If Not frm2 Is Nothing Then
                    frm2.Hide()
                End If
 
                frm1.Show()
            Case "frm2"
                If frm2 Is Nothing Then
                    frm2 = New FrmAddClient2
                    frm2.MdiParent = Me
                End If
 
                If Not frm1 Is Nothing Then
                    frm1.Hide()
                End If
 
                frm2.Show()
            Case Else
 
        End Select
 
    End Sub
 
End Class
 
 
 
####### FrmAddClient1########
Public Class frmAddClient1
    Private Sub SimpleButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextButton.Click
        Me.ValidateChildren()
        If DxErrorProvider1.HasErrors Then
            MessageBox.Show("Please fix all errors to continue.")
        Else
##I add stuff to my record class here##
            Dim myParent = Me.MdiParent
            myParent.FormHandler("frm2")
 
        End If
    End Sub
    Private Sub FrmAddClient1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
 
        Me.Activate()
        Dim button As DialogResult = MessageBox.Show("Closing this form will result in the loss of all unsaved data,", "Closing form", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
        If button = Windows.Forms.DialogResult.Cancel Then
            e.Cancel = True
        ElseIf button = Windows.Forms.DialogResult.OK Then
            e.Cancel = False
        End If
    End Sub
End Class
 
 
###########FrmAddClient2############
##looks much the same as FrmAddClient1, but has a back button##
 
Public Class FrmAddClient2
 
    Private Sub SimpleButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BackButton.Click
        Dim myParent = Me.MdiParent
        myParent.FormHandler("frm1")
    End Sub
End Class

Open in new window

LVL 1
Mr_OzAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

omegaomegaDeveloperCommented:
Hello, Mr_Oz,

I think you are having a problem because the Public variables frm1 and frm2 continue to hold a reference to the form that has been closed.  (Even though the form is closed, it is not Nothing.)  Therefore your test:

     If frm1 Is Nothing Then

prevents re-creating a new instance of frmAdClient1 and likewise for frm2).

You could fix this by adding the event handlers shown in the attached snippet to your code in FrmMain.

Cheers,
Randy

    Private Sub frm1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles frm1.FormClosed
 
        Me.frm1 = Nothing
 
    End Sub
 
    Private Sub frm2_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles frm2.FormClosed
 
        Me.frm2 = Nothing
 
    End Sub

Open in new window

0
Mike TomlinsonMiddle School Assistant TeacherCommented:
Another option is to change your underlying approach to the problem using the "default instance" of your child forms.

Instead of using the "New" keyword, simply use the Forms NAME itself.

This:

    frm1 = New frmAddClient1
    frm1.MdiParent = Me
    frm1.Show()

Gets replaced with:

    ' note that we are NOT using the "New" keyword anywhere here!
    frmAddClient1.MdiParent = Me
    frmAddClient1.Show()

There can only ever be ONE "default instance" and this instance can be accessed from anywhere in your application.  So hiding showing forms from each other becomes very simple:

    ' from within frmAddClient2
    frmAddClient1.Show()
    Me.Hide()
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Mr_OzAuthor Commented:
Thanks Omega Omega,

That fixed part of the problem, now if I close the AddClient1frm I can open a new one by clicking the nav bar item.  However I am still getting funny behavior.  If I do this

frmMain (clicknavbar)---> Frm1 opens (click cancel button or close window)-----> FrmMain (clickNavbar) -----> Frm1 opens again no problem

But if I do this...

FrmMain (clicknavbar)---> Frm1 opens (click Next)-----> Frm2 opens and Frm 1 hides (click back on frm2) -----> Frm1 shows (frm2 hides)---> click cancel or close form1 (form1 closes)--->  FrmMain (click navbar to openFrm1 (like above)---->

I get an error on
            Case "frm1"
                If frm1 Is Nothing Then
                    frm1 = New frmAddClient1   --------------> error on this line
                    frm1.MdiParent = Me
                End If

The error says:
Object reference not set to an instance of an object
Try
using the 'new' keyword to create and object instance
or
check to determine if the object is null before calling this method

Do you know why this would happen?  I do use the 'new' keyword so I do not understand why this is happening.
0
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

omegaomegaDeveloperCommented:
Hello, Mr_Oz,

I like Idle_Mind's approach.  It may require a few more keystrokes to change your existing code, but seems much cleaner in the end.

Unless you have some underlying reason that prevents you from using it, I would choose it.  

Cheers,
Randy
0
Mr_OzAuthor Commented:
Sorry Idle_Mind I had not seen your response.

Let me see if I can figure out that approach as for these forms there will only ever be one instance.
0
omegaomegaDeveloperCommented:
Hello, Mr_Oz,

Sorry, I hadn't seen your follow-on question when I posted.  

I don't seem to be able to generate the error that you are seeing, and (like you) can't understand why such an error would be reported on that line.  I do have a problem if I close frm2.  In this case, frm1 is still open (just hidden) and so triggers the message "You may only add one client at a time" when trying to create a new instance.

You might try to solve this second problem by making sure all AddClient forms are closed and setting all frmN variables to Nothing in the event handler.  The way things are now, closing the hidden forms would cause repeats of the Close warning message.  You would need to make changes to the AddClient forms to deal with this.  It becomes very messy -- even worse with more AddClient forms.

I can't offer any ideas about the "Object reference not set to an instance of an object" problem.

I still recommend using Idle_Mind's approach.

Cheers,
Randy
0
Mr_OzAuthor Commented:
OK, again thanks for the advice.  I tried to take Idle Minds advice.

This is what I did:

I nixxed the FormHandler subroutine and the public variables in FrmMain.  I also took out the check that states only one client can be open at a time since that is all that is possible it appears with this new method. Now I just have what is shown below in the code box.

Now it is behaving exactly as before with less code.  But I have a different exception for the same scenario as before, now it does this.

frmMain (clicknavbar)---> Frm1 opens (click cancel button or close window)-----> FrmMain (clickNavbar) -----> Frm1 opens again no problem

But if I do this...

FrmMain (clicknavbar)---> Frm1 opens (click Next)-----> Frm2 opens and Frm 1 hides (click back on frm2) -----> Frm1 shows (frm2 hides)---> click cancel or close form1 (form1 closes)--->  FrmMain (click navbar to openFrm1 (like above)---->

I get an error on FrmMain

frmAddClient1.Show()
 
 InvalidOperationException was unhandled
 An error occurred creating the form. See Exception.InnerException for details.  The error is: Object reference not set to an instance of an object.  

I must still be doing something wrong, any advice?


#### Here is FrmMain (MDI parent form) ######
 
    Private Sub NavBarItem1_LinkClicked(ByVal sender As System.Object, ByVal e As DevExpress.XtraNavBar.NavBarLinkEventArgs) Handles NavBarItem1.LinkClicked
 
        frmAddClient1.MdiParent = Me
        FrmAddClient2.MdiParent = Me
        frmAddClient1.Show()
 
    End Sub
 
 
#######Here is FrmAddClient1 ##################
 
    Private Sub SimpleButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextButton.Click
 
            FrmAddClient2.Show()
            Me.Hide()
 
End Sub
 
##The closing event is the same as before##
 
############Here is FrmAddClient2####################
 
Public Class FrmAddClient2
 
    Private Sub SimpleButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SimpleButton1.Click
        frmAddClient1.Show()
        Me.Hide()
    End Sub
End Class

Open in new window

0
Mike TomlinsonMiddle School Assistant TeacherCommented:
I can't get it to fail...  =\

I'm guessing you have something in the Load() and/or Shown() event that is causing the problem.

Try the code below with a new bare bones project and see if it works as expected.  This will tell us if the problem is only with your existing application:

Public Class Form1 ' <-- MdiParent

    Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click
        Form2.MdiParent = Me
        Form2.Show()
    End Sub

End Class

Public Class Form2 ' <-- MdiChild

    Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click
        Form3.MdiParent = Me.MdiParent
        Form3.Show()
        Me.Hide()
    End Sub

End Class

Public Class Form3 ' <-- MdiChild

    Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
        Form2.MdiParent = Me.MdiParent
        Form2.Show()
        Me.Hide()
    End Sub

End Class
0
Mr_OzAuthor Commented:
thanks idle mind,

OK so I did up a dummy project and it worked as you said.

I literally have almost everything commented out in my code I have nothing in the load or show events :(

If i open FrmClientAdd1 from navbar and close without hitting next or back things work fine

If I open FrmClientAdd1 from navbar and go next to form 2 and close form 2 things work fine

If I open FrmClientAdd1 from navbar and go next to form 2 and back to form1 then next to form2 again and close form2 things work fine

If I open FrmClientAdd1 from navbar and go next to form2 and back to form1 and close form1 then it blows up when trying to click the navbar to open Form1 again.

Same error as above on  frmAddClient1.MdiParent = Me

I am stumped...
0
Mike TomlinsonMiddle School Assistant TeacherCommented:
=\

Usually when things act "weird" I find one of two things:

(1) The project is "corrupt".  Never really an explanation found in these ones...just that re-creating the project from scratch and copying the code over results in a working project.  Yay Microsoft!

(2) There are THIRD-PARTY controls being used in the Project and they are behaving badly.  Are you using anything not provided with the .Net framework?
0
Mr_OzAuthor Commented:
Yeah I am using some DevExpress components for layout management and look and feel support.  However when I recreated your dummy project I used the same components to try and identify if they were the problem and everything worked.  I think it looks like I will have to recreate the project from scratch... Ouch.

I do thank you for your help your solution does appear to work for my original issue, so I will award you all the points.  Thanks again for your prompt responses.

Thank you.
0
Mr_OzAuthor Commented:
Great response times and your explanations were easy to follow.  Thank you.
0
Mike TomlinsonMiddle School Assistant TeacherCommented:
You're welcome!  Please let us know if re-creating the project doesn't fix the issue (I hope that isn't the case...wasted time is never fun).

Good luck...  =)
0
Mr_OzAuthor Commented:
FYI to others who may read this in the future.  Idle mind was correct, I luckily had a backup so I did not have to reconstruct the whole project just 2 days worth, but it did fix the problem so apparently something was corrupt in my project.  The accepted solution now works as intended.

0
Mike TomlinsonMiddle School Assistant TeacherCommented:
Glad you got her working again!  Thanks for posting back...   =)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.