Previous | Index | Next 

[PRB] An MDI Child form can mistakenly display a menu bar

The .NET Framework exhibits a weird behavior – which should be more properly considered as a bug – that can affects migrated applications under certain conditions.

Consider this scenario: inside an MDI form named MDIForm1 your code displays an MDI child form named Form1; also, in the handler of Form1.Activate event your code displays a second MDi child form, named Form2.

The problem: the .NET Framework correctly fires two MDIChildActivate events inside MDIForm1 – one for Form1 and one for Form2 – both events fire only after Form2 has been activated and therefore the MDIForm1.ActiveMdiChild property always return a reference to Form2.

This scenario is quite unlikely, yet it is possible and in fact one of our users brought it to our attention. This .NET bug can affect migrated projects in two ways.

First, we map the MDIForm1.ActiveForm VB6 property to the ActiveMdiChild .NET property; in the abovementioned scenario this means that in some cases the ActiveForm property of an MDI form might return an incorrect value.

Second, the VB Migration Partner’s support library internally uses the ActiveMdiChild property to move menu bars from an MDI child form to its MDI parent form. If the ActiveMdiChild property returns an incorrect value, the mechanism won’t work correctly. As a result, you will see that the MDI child form displays a menu bar under .NET (but not in the original VB6 project).

You can solve the second issue by ensuring that you never display an MDI child form from inside the Activate event of another MDI child form. In other words you should fix the migrated code from

        Private Sub Form_Activate() Handles MyBase.Activate
            Form2.Show
        End Sub

to

        Private Sub Form_Activate(ByVal sender As Object, ByVal e As EventArgs) _
                Handles MyBase.Shown
            Form2.Show
        End Sub

The easiest way to do so is by means of a ReplaceStatement in the original VB6 code:

        ' (note that next lines are to be inserted as one physical comment)
        '## ReplaceStatement Private Sub Form_Activate(ByVal sender As Object,
                  ByVal e As EventArgs) Handles MyBase.Shown
        Private Sub Form_Activate() Handles MyBase.Activate
            Form2.Show
        End Sub

 

Previous | Index | Next