LiKao
LiKao

Reputation: 10658

Vb.Net panel creates contained form in single pieces

I am currently trying to create a single window application in which the content of the window is able to change (both the content of controls as well as the controls themselves). I templated each specific control layout using forms, then for the main window I created a form that only consists of a single panel. I load the forms within this panel. When the layout changes I clear the panel and then load the new layout form into the panel.

However if I do it like this, for a brief moment when the new form is loaded, the title window of the form seems to appear within the panel and also the controls flicker briefly as if they were created one by one instead of all appearing at once.

I already tried various combinations of hiding/unhiding the form as well as the panel to which the form is loaded. I also tried stoping the form from being displayed to early by calling SuspendLayout() before adding the form and ResumeLayout() afterwards on the panel.

Is there any way to get the form to be drawn all at once instead of piece by piece?

EDIT

I finally got the pendrive with the code back (this is project I am helping someone else with).

Here are the relevant portions of the code:

Public Class MainWindow

    Dim currentPanel As Control

    ...

     Private Sub MainWindow_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        Me.Location = New Point(0, 0)
        Me.Size = SystemInformation.PrimaryMonitorSize

        mainpanel.Size = SystemInformation.PrimaryMonitorSize

    End Sub

    ...

    Sub nextTrial()
        TrialSet.currentTrial = TrialSet.currentTrial + 1
        If TrialSet.currentTrial < TrialSet.numTrials Then
            Dim TrialFrm As Trial
            TrialFrm = New Trial(TrialSet.getTrial(TrialSet.currentTrial))
            TrialFrm.TopLevel = False
            setForm(TrialFrm)
        Else
            Dim doneFrm As DoneForm
            doneFrm = New DoneForm
            doneFrm.Toplevel = False
            setForm(doneFrm)
        End If
    End Sub

    ...

    Private Sub setForm(ByVal ctrl As Control)
        mainpanel.Hide()
        mainpanel.SuspendLayout()
        mainpanel.Controls.Clear()
        If Not (currentPanel Is Nothing) Then
            currentPanel.Dispose()
        End If
        currentPanel = ctrl
        mainpanel.Controls.Add(ctrl)
        ctrl.Hide()
        mainpanel.Show()
        mainpanel.ResumeLayout()
        ctrl.Show()
    End Sub

End Class

This may be a bit of a hack for which there is a better solution (I am not that familiar with VB).

Mainpanel is the panel in which the forms that I am using should be contained (the window only consists of this panel).

The main part is the SetForm method. In this I am trying to remove the old form (including disposing it) and to add the new form. I also tried various other combinations of hide, unhide, SuspendLayout and ResumeLayout both for the main panel as well as for the new form (passed to the method as ctrl).

In the Form itself I do the following:

Private Sub Trial_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        Me.Location = New Point(0, 0)
        Me.Size = SystemInformation.PrimaryMonitorSize
...
End Sub

With this I can see the window border of the form including the close button etc. appear for a brief moment of time.

Upvotes: 1

Views: 202

Answers (1)

Hans Passant
Hans Passant

Reputation: 942090

There are multiple explanations for this, you don't give us any hint by not showing your code. The simplest way to go about this is to make the problem debuggable. Copy/paste this code into the form class that you put in the panel:

Protected Overrides Sub OnHandleCreated(e As EventArgs)
    MyBase.OnHandleCreated(e)
End Sub

Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
    MyBase.OnFormClosed(e)
End Sub

Set a breakpoint on both methods. With the expectation that you see OnHandleCreated() execute multiple times. The debugger's Call Stack window shows you what code caused this. By far the simplest explanation is that you set the Visible property to True to soon (or called Show), before you set the FormBorderStyle to None. Swap the statements to fix. There are others, let the debugger tell you why this happened.

Another expectation is that you don't get a breakpoint on the OnFormClosed() method. This is very, very bad and will cause your program to progressively get slower, ultimately crashing with an "Error creating window handle" exception. That is caused by a bug in your code that removes the form again, using the panel's Controls.Clear() or Remove/At() method instead of calling the form's Dispose() method. Calling Dispose() is a rock-hard requirement.

Upvotes: 3

Related Questions