Click here to Skip to main content
Click here to Skip to main content

Working With Paneled Forms (Paneled User Controls) in Windows Applications

, 22 Jul 2005 CPOL
Rate this:
Please Sign up or sign in to vote.
Describes how-to of using User Controls with Panels on Windows Forms.

Figure 1 - Main Application Form.

Figure 2 - User Control 1.

Figure 3 - User Control 2.

Figure 4 - User Control 3.

Figure 5 - Lefe Made Easier with Whidbey!!!

Introduction

There are many different approaches to work with displaying various forms one after the other when developing a Windows application. Let it be clear that I am not talking about MDI applications, but those applications which consists of various forms displaying information, taking input, and any other task associated to them. At a time, one or more form is displayed and when some command or operation occurs, that form is cleared away and a new form is displayed. This is easily conquered by:

    Dim newForm As New Form2()
    newForm.Show()

Which can be easily followed by removing the previous form, and can also allow data to be passed among the forms using either user defined constructors or simply accessing the control's properties and setting them through the new object created, for instance:

    newForm.lblName.Text = oldForm.txtName.Text.Trim()

This is one of the most widely used methods of developing a Windows application, at least to my knowledge. But considering that one has to develop such an application where most of the form’s layout is to be the same for every form, for instance, menus, pictures, etc., why should each common control be repeated and coded over again? I, myself, have been through this experience. And having sought out expertise on this, I found out that most people went using the form swapping method even though their application had to reconstruct or create a large number of controls over and over again. It was then that I decided to go with Tab controls. Although not that hot looking, they did their work.

After this I turned towards using User Controls. And thus this article explains how to go about and use them. The best use of user controls with panels I have seen, to date, is the My Movie Collection Started Kit included in the Visual Studio Beta 2. (Note: I still have to look at the factor of memory consumption, for it might be that the old method could be a bit jerky, but faster and feasible.)

Using Paneled Forms (VS2003)

I will start by explaining how I managed to accomplish the afore-mentioned task using Visual Studio 2003 and .NET 1.1. Let’s start by creating a simple Windows form. My main application form (myMainForm.vb) can be seen in Figure 1. This form consists of a menu, a label, a picture, and two buttons. The grayish area in the right-hand corner is a panel. This panel will hold the user controls. The panel in my application is of 450x350. I will, thus make my user controls to be 450 x 350 too.

Thus next are the user controls that I use, they are as shown in Figures 2, 3, & 4.

Now, let us explore the code. On application start, the myMainForm is displayed, as shown in figure 1. Now when we press the ‘First Form’ button, we want to display our first control shown in figure 2, and when we press ‘Second Form’, we want to display our second control shown in figure 3. To accomplish this, we use the following lines of code:

    Private Sub btnFirst_Click(... , ...) Handles btnFirst.Click
        ' firstControl is one of the user controls.
        Dim tempObject As New firstControl
        pnlMain.Controls.Clear() ' pnlMain is the Panel.
        pnlMain.Controls.Add(tempObject)
    End Sub

    Private Sub btnSecond_Click(... , ...) Handles btnSecond.Click
        ' secondControl is one of the user controls.
        Dim tempObject As New secondControl 
        pnlMain.Controls.Clear() ' pnlMain is the Panel.
        pnlMain.Controls.Add(tempObject)
    End Sub

This piece is quite simple actually, and the magic lies in the two statements pnlMain.Controls.Clear() and pnlMain.Controls.Add(tempObject). The first line releases the panel of any controls it might be holding or displaying, and the other sets the new control to be displayed in the panel. And voila! On button click, the appropriate user control is loaded into the panel.

Now suppose we want to change our control from within the control. This is extremely useful when we want to transfer some data from one control to another. If you look at figure 2, you will see a button labeled ‘Next!’. What this button does is that it gets the first and last name entered by the user and passes it to a new control being built, figure 4, which will display this information and can process on this information. Here is the appropriate function:

    Private Sub btnNext_Click(... , ...) Handles btnNext.Click
      Dim tempObject As New thirdControl
      tempObject.lblFirstName.Text = "You entered the following" & _ 
                        " Start Name: " + Me.txtFirstName.Text.Trim()
      tempObject.lblLastName.Text = "You entered the following Last Name: " _
                                                  + Me.txtLastName.Text.Trim()
      Me.Parent.Controls(0).Controls.Clear()
      Me.Parent.Controls(0).Controls.Add(tempObject)
    End Sub

The first few lines are quite easy to understand, as they simply initialize an object of the thirdControl and set the two labels to their value. The tricky part comes when we want to swap the current control being displayed by the new one. As we are in the current control, we cannot directly access the panel on the main form. But we know that the parent is the main form, thus we simply access the panel through Parent.Controls(0) and set the controls to be cleared. And then add the new control that is to be displayed.

The major problem in this method, which is removed in Whidbey, is that we have to be sure as to which index our control lies on, or else we might be playing with the wrong controls… To get the index of the control, we have to look in the InitializeComponent() in the ‘Windows Form Designer generated code’. After the initialization of every component, at the very end, the form/user-control is initialized. In this case, myMainForm is initialized as:

    '
    'myMainForm
    '
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    Me.BackColor = System.Drawing.Color.LightGray
    Me.ClientSize = New System.Drawing.Size(628, 442)
    Me.Controls.Add(Me.pnlMain)     
    Me.Controls.Add(Me.btnSecond)    
    Me.Controls.Add(Me.btnFirst)    
    Me.Controls.Add(Me.picMain)        
    Me.Controls.Add(Me.lblMain)     
    Me.Menu = Me.myMenu
    Me.Name = "myMainForm"
    Me.Text = "Paneled Form Example"
    Me.ResumeLayout(False)

We see that the first to be added is pnlMain, i.e., the Panel. Thus, it is at index 0. Similarly btnSecond is at index 1, btnThird is at index 2, and so on. We can also change the index number of a control. Let’s say that I want the panel to be at index 2. To do so, we simply add the panel at the third position, i.e., after two controls…

There is another scenario that remains to be discussed. And that is: what if we want to get some information to the main form from a user control being displayed. The solution is again quite simple, Panel1 being a member of the main form, we can access its properties from the code there.

    Panel1.Controls(0).Controls.Item(0).Text
    Panel1.Controls(0).Controls.Item(1).Text
    Panel1.Controls(0).Controls.Item(2).Text
    Panel1.Controls(0).Controls.Item(3).Text

This accesses the Panel’s control at index 0. As we have been displaying a single user control at a time, the user control will be at index 0 of the panel. (We can include various user controls at the same time by using panels within panels.) Next we get the collection of controls of the user control, and select the item with its index, whose value we want. We can also do stuff like set the background color of a control, or change its font, or set an image, etc. In other words, after having accessed the item, we can perform any function on it, as long as it is appropriate. The problem being that if you get some item indexes wrong, then you might be using some specific function, like the Lines() function of RichTextBox, on some item that doesn’t provide the function. This will result in an error at runtime. (But then, Whidbey removes this problem by allowing names also instead of just indexes, check it out below.)

Using Paneled Forms (VS2005 Beta2)

As I mentioned earlier, this method is extremely mind-boggling, especially with one keeping track of indexes and parents, etc…

The same task has been made simpler in Whidbey. The major change being that now we can access the controls by their name. For instance, I can use the statement Controls.Item(“PnlMain”) to access the Panel control instead of having to worry about index number. And Controls.Item(“txtTextBox1”) to access items in a control. This absolutely makes life a lot easier (Figure 5).

Note: Figure 5 represents a previous approach I was trying to do, and as I said in an earlier version of this article that Controls("PnlMain") would do the trick. It turned out that it threw back errors. I spent the day trying to figure it out and found the right statement to use:

Me.ParentForm.Controls.Item("myPanel").Controls.Add(tempObject)

Note that instead of using Me.Parent, I am now using ParentForm. This is easy to handle, as a parent might be a GroupBox, Panel itself, or any other container...

Notice that I am accessing the controls of the ParentForm and selecting the item "myPanel".

Last Words

I am planning on writing a whole program using these techniques. I will upload the link to this article when I have done so.

This is me signing out. Please feel free to contact me at msk.psycho@gmail.com. Comments & criticism are both highly appreciated...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

msalmank
Web Developer
Pakistan Pakistan
I am currently working as a Senior Software Developer (.Net) in Premier POS, Inc. Focused mainly on Windows Application Development, i am now looking for inspiration to work on Windows Presentation Foundation.

Comments and Discussions

 
GeneralMy vote of 5 Pinmembermanoj kumar choubey23-Feb-12 22:53 
Generalminimizing the userform Pinmemberbrindhakr4-Apr-09 1:25 
GeneralRe: minimizing the userform Pinmembermsalmank23-Jun-09 8:59 
GeneralWorking With Paneled Forms Pinmembermaximus200721-Sep-07 15:25 
GeneralThanks Salman Pinmembergiamvar14-Jul-07 4:25 
QuestionControlling MDI child form from MDI parent panel PinmemberLuxCoder2-Apr-07 9:57 
AnswerRe: Controlling MDI child form from MDI parent panel Pinmembermsalmank30-Jul-08 4:57 
GeneralForms inheritance PinmemberDmitry Shonichev1-Nov-06 3:12 
GeneralRe: Forms inheritance Pinmembermsalmank2-Nov-06 4:06 
QuestionException Occur while using panel to show the form Pinmembererlakhangarg8-May-06 20:26 
AnswerRe: Exception Occur while using panel to show the form Pinmembermsalmank9-May-06 7:48 
GeneralRe: Exception Occur while using panel to show the form PinmemberDogMa3x7-Sep-07 12:07 
Questionhow about this? PinmemberRom200020-Feb-06 22:55 
GeneralOut of memory Exception Pinmemberdemazing7-Oct-05 10:53 
GeneralRe: Out of memory Exception Pinmembermsalmank7-Oct-05 18:43 
GeneralRe: Out of memory Exception Pinmemberdemazing7-Oct-05 23:47 
GeneralRe: Out of memory Exception Pinmembermsalmank8-Oct-05 7:29 
GeneralCommon Data Store for the various User controls Pinmemberrickman987651-Aug-05 6:59 
GeneralRe: Common Data Store for the various User controls Pinmembermsalmank1-Aug-05 8:10 
GeneralBad link on "source", bad zip on "demo" Pinmemberfwsouthern22-Jul-05 9:51 
GeneralForm resizing ? Pinmemberfwsouthern22-Jul-05 14:12 
GeneralRe: Form resizing ? Pinmembermsalmank22-Jul-05 21:45 
GeneralRe: Form resizing ? Pinmembermsalmank22-Jul-05 21:54 
GeneralRe: Form resizing ? PinmemberMBursill25-Jul-05 21:54 
GeneralRe: Form resizing ? Pinmembermsalmank27-Jul-05 10:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.141015.1 | Last Updated 22 Jul 2005
Article Copyright 2005 by msalmank
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid