MDI Problem, Please Help

CHR15.NET

New member
Joined
Dec 7, 2005
Messages
4
Programming Experience
Beginner
Hi guys….I got a problem with MDI (Multiple Document Interfaces). First, I am a newbie, and I need to make a MDI application for study purposes. But somehow, I got stuck. So, this is the problem….

The forms:
frmMyParentForm
frmCommandForm
frmForm3

frmMyParentForm, as its name, it’s the parent form. And frmCommandForm is like a control panel, where user could open frmForm3.

At the frmCommandForm, there is a button named "btnForm3" and its text "Open Form3", which when it’s clicked, it will open the frmForm3. And this is where the problem also…..when it’s click, it will ALWAYS open a new frmForm3, which I don’t want to…..What I want is, if the frmForm3 has been opened before, and the user clicks again the button “btnForm3”, it will make the frmForm3 got focus.

Somehow, I just got stupid, and have no clue how could I do that….luckily, found this forum, with full of hope that someone would help.

Thanks a lot…

Code at frmMyCommandForm for btnOpenForm3

VB.NET:
Private Sub btnOpenForm3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenForm3.Click

        Try

            Dim f3 As frmForm3

            If f3 Is Nothing Then

                f3 = New frmForm3

            End If

            With f3

                .StartPosition = FormStartPosition.CenterScreen
                .MdiParent = MDI.frmmyParentForm.ActiveForm
                .Show()

            End With

        Catch ex As Exception

            MsgBox(ex.ToString)
            Application.Exit()

        End Try

    End Sub


Sincerely,
Chris
 
Last edited:
There are many ways (realy many) how to preserve multiply instances of the same form and for the start i'd recommend very simple one.

Declare module scope boolean i.e. fOpen / Public fOpen as Boolean

Then when you want to show the frmForm3 simply check is it false.
VB.NET:
If fOpen = False then
 fOpen = true
 Dim nform as form = new frmForm3
 nform.MDIParent = me.MdiParent
 nform.Show()
Else
[COLOR=darkgreen]'use Active method as it activates the form and gives it focus[/COLOR]
End if

Also don't forget to set fOpen boolean to false each time you close the form
Put this code in Closing event of frmForm3:
VB.NET:
fOpen = False

HTH
Regards ;)
 
[Problems RESOLVED]

Hi Kulrom, thanks for your reply. It did help, but in the perspective manner. So, finally I have resolved it. Now I want to contribute it as well:

I am making a simple tutorial in creating MDI for my conclusion, and will to share with others my experience.

Let's get started !

The CASE:

You are trying to make an MDI Application, which has:

1. A parent form --> as the name for example: frmParentForm.
2. Children forms --> one of them is the command panel which has buttons to navigate users to access / open other child forms. In this example, the Command Panel form has the name frmCommandPanel.
3. In the frmCommandPanel you have a button or maybe more buttons to open one or more children forms. But in this example we'll use only one button and it's named as: btnOpenChildForm. btnOpenChildForms opens a child form when it's clicked.

The PROBLEM:

1. Everytime you click the button which opens the Child Form, it will always create a new instance, which you don't want those. But you only one instance, and if the Child Form has been opened, you want just to activate it to note the user that it has been opened, and if it has been opened but it is minimized, and the user clicks again the button, you want the child from to be maximized or normaled.
2. After you close the frmChildForm, then you try to click the button which opens the child form again and you get an error of OBJECTDISPOSEDEXCEPTION.

If that the cases and your problems. Then this simple tutorial is for you.

Let's go solve your problem !

The STEPS:

1. Create the frmParentForm, and set its IsMDIContainer property to TRUE.
2. Create the frmCommandPanel. Add a button on it, and name it : btnOpenChildForm.
3. Next, you'll want that the frmCommandPanel is showed automatically as the child form of frmParentForm, when the application is first to start.
4. So, at Design Mode of the frmParentForm, right click over it and select VIEW CODE, let's dive into coding:

VB.NET:
Option Strict On

Public Class frmParentForm
    Inherits System.Windows.Forms.Form
    
'We're not going to talk about Windows Form Generated Code, so let's skip it....
+ Windows Form Generated Code
    
    'Define the Variables here at first as a FRIEND variable, so that it could be accessed later by other Children Forms. Don't define
    'the variable as a local variable for the form, if you want it to be able to call the variable in other class. 
    '(This was where my mistake, I defined the variable as the local variable...)
    Friend CommandPanel as frmCommandPanel
    
    'Then at the LOAD EVENT....You Type:
    Private Sub frmParentForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Try
       If CommandPanel Is Nothing Then
                CommandPanel = New frmCommandPanel
                With CommandPanel
                    .MdiParent = frmParentForm.ActiveForm
                    .StartPosition = FormStartPosition.CenterScreen
                    .Show()
                End With
           End If
    Catch ex As Exception
            MsgBox(ex.ToString)
     Application.Exit()                        
        End Try
        
    End Sub
5. Create another Form and name it: frmChildForm. Add a button on the frmChildForm and name it : btnCloseChildForm.

6. At the frmCommandPanel's code....let's dive into the code:
VB.NET:
     Option Strict On

Public Class frmCommandPanel
    Inherits System.Windows.Forms.Form

'Define the variable here...
Friend ChildForm as frmChildForm

'Just skip this part....    
+ Windows Form Designer Generated Code

'Then....at the btnOpenChildForm:
Private Sub btnOpenChildForm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenChildForm.Click
        
        'See if an instance of the ChildForm has been created, if not then create one
        If ChildForm is Nothing Then
        
            ChildForm = New frmChildForm
            
            'Then set its MDIParent to frmParentForm,
            'and its startposition to CenterScreen or anywhere you like
            'finally show the form
            With ChildForm
            
                .MDIParent = frmParentForm.ActiveForm
                .StartPosition = FormStartPosition.CenterScreen
                .Show()
                
            End With
            
            'And if an instance of the ChildForm has been created, but it's on minimize state then,
            'bring it to NORMAL State or any state you like...
            ElseIf Not (ChildForm is Nothing) Then
            
                If ChildForm.WindowState = FormWindowState.Minimized Then
                
                    ChildForm.WindowState = FormWindowState.Normal
                    
                End If
                
        'If it's already created and the user tries to click the btnOpenChildForm again,
                'do not create another instance, instead just ACTIVATE it.
                
                ChildForm.Activate()
                
        End IF

End Sub
7. This step is to prevent the OBJECTDISPOSEDEXCEPTION comes up to surface after you close the child form. To do that you'll have to write codes at the frmChildForm:
VB.NET:
Option Strict On

Public Class frmEnterNewFoodReciepe
    Inherits System.Windows.Forms.Form
    
'Skip this part, since we're not going to talk about it....
+ Windows Form Designer Generated Code

'At the btnCloseChildForm Click Event, and Closed Event, type:...

Private Sub btnCloseChildForm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCloseChildForm.Click

        'Close the frmChildForm
        Me.Close()
        
        'This line is very important to prevent OBJECTDISPOSEDEXCEPTION occurs.....which got me for days before finally realized
        ' it...
        ChildForm = Nothing

End Sub

Private Sub btnCloseChildForm_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed

        'After the frmChildForm is Closed, then Dispose it...
        Me.Dispose()
        
        'And set the ChildForm to Nothing again....
        ChildForm = Nothing

End Sub

8. Congratulations, you finally made a simple MDI Application Interface...It's time to test your code !

Hope that would help to explain and to help you to understand better about Multiple Document Interfaces.

Best regards,
Chris

Note, you can find this code in eXtremeVisualBasicTalk(http:\\www.visualbasicforum.com\). My NickName there is Kampfcoder.
 
Very good tutorial :).

Here's a tip to help shorten the code.
In the btnOpenChildForm_Click method, in addition to checking if the variable ChildForm is equal to Nothing, also check if it has been disposed. This will enable you to leave out the code where you dispose of and set equal to Nothing the ChildForm variable.
VB.NET:
If ChildForm Is Nothing OrElse ChildForm.IsDisposed Then
The order is important here because of the use of the ShortCircuiting OrElse operator. The OrElse is considered ShortCurcuiting because if the first expression is False, the second expression isn't evaluated. If a simple OR operator were used in the case where ChildForm is equal to Nothing an exception would be thrown.
 
Back
Top