Many controls can contain other controls, grouping them. The Form control is the ultimate container, but it serves a larger purpose than just containing other controls. The form is the center of Windows Forms-based applications, having many unique properties and methods that empower the Form control to fulfill its role. These include properties such as AcceptButton, Modal, and WindowState, and methods such as Activate and Close. Chapter 5 covers the Form control thoroughly.

Some controls exist only to fill the role of container. They have very few properties, and all their methods are either inherited or overridden from the Control class. They cannot receive focus, although they may play a role in the tab order. Their sole mission is to group other controls to a common purpose. That purpose may be ergonomic, e.g., using a container control to put a border around several labels and text boxes used for gathering address information. The purpose may also be directly functional, e.g., grouping several radio buttons so they become mutually exclusive.

The two controls that exist only to be containers are GroupBox and Panel. They are similar in purpose, but have some very different features. In short, the GroupBox displays its Text property as a caption. It cannot scroll. The Panel control, on the other hand, can scroll but does not display its Text property and cannot have a caption.

The class hierarchy shown in Figure 13-1 explains this behavior. The GroupBox class is derived directly from Control, while the Panel control is derived from Control via the ScrollableControl class, thereby gaining the ability to have scrollbars. Neither GroupBox nor Panel are derived from ContainerControl, even though they are containers.

The ContainerControl class is perhaps misnamed. A control does not have to derive from ContainerControl to be a container, but it has to derive from Control (which has a Controls property that returns a collection of contained controls). The ContainerControl class' main purpose is to deal with focus management.

The Panel class has a read/write Text property that overrides the Control.Text property, but it does not display as part of the control.

If either a GroupBox or Panel control's Enabled property is set to false, then all the controls contained within will also be disabled. Likewise, if a GroupBox or Panel control's Visible property is set to false, then none of its child controls will be visible.

Both the GroupBox and Panel controls were demonstrated in Example 11-9 and Example 11-10. Those examples will be reprised here in Example 13-1 (in C#) and Example 13-2 (in VB.NET), with a few minor modifications. The lines of code that differ from the examples in Chapter 11 are highlighted.

When the programs in Example 13-1 and Example 13-2 are compiled and run, they yield the form shown in Figure 13-1. This is similar to that shown in Figure 11-7, except that the panel containing the font style checkboxes is intentionally made short to require a vertical scrollbar, and that panel also has a BorderStyle applied to it.

Figure 13-2. Containers


Example 13-1. Containers in C# (Containers.cs)


using System;
using System.Drawing;
using System.Windows.Forms;
namespace ProgrammingWinApps
 public class Containers : Form
 Label lbl;
 Panel pnl;
 int yDelta;
 RadioButton rdoAppearanceNormal;
 RadioButton rdoAppearanceButton;
 RadioButton rdoCheckAlignMiddleLeft;
 RadioButton rdoCheckAlignMiddleRight;
 RadioButton rdoTextAlignMiddleLeft;
 RadioButton rdoTextAlignMiddleRight;
 RadioButton rdoTextAlignMiddleCenter;
 FontStyle[ ] theStyles;
 public Containers( )
 Text = "Containers";
 Size = new Size(350,375);
 lbl = new Label( );
 lbl.Parent = this;
 lbl.Text = "The quick brown fox...";
 lbl.Location = new Point(0,0);
 lbl.AutoSize = true;
 lbl.BorderStyle = BorderStyle.Fixed3D;
 yDelta = lbl.Height + 10;
 // Get the FontStyles into an array
 FontStyle theEnum = new FontStyle( );
 theStyles = (FontStyle[ ])Enum.GetValues(theEnum.GetType( ));
 pnl = new Panel( );
 pnl.Parent = this;
 pnl.Location = new Point(0, yDelta );
 pnl.Size = new Size(150, (theStyles.Length - 1) * yDelta);
 pnl.BorderStyle = BorderStyle.Fixed3D;
 pnl.AutoScroll = true;
 int i = 1;
 CheckBox cb;
 foreach (FontStyle style in theStyles)
 cb = new CheckBox( );
 cb.Location = new Point(25, (yDelta * (i - 1)) + 10);
 cb.Size = new Size(75,20);
 cb.Text = style.ToString( );
 cb.Tag = style;
 cb.CheckedChanged += new 
 if (cb.Text = = "Regular")
 cb.Checked = true;
 GroupBox grpAppearance = new GroupBox( );
 grpAppearance.Parent = this;
 grpAppearance.Text = "Appearance";
 grpAppearance.Location = new Point(175,yDelta);
 grpAppearance.Size = new Size(150, yDelta * 3);
 rdoAppearanceNormal = new RadioButton( );
 rdoAppearanceNormal.Parent = grpAppearance;
 rdoAppearanceNormal.Text = "Normal"; 
 rdoAppearanceNormal.Location = new Point(10, 15);
 rdoAppearanceNormal.Checked = true;
 rdoAppearanceNormal.CheckedChanged += 
 new System.EventHandler(rdoAppearance_CheckedChanged);
 rdoAppearanceButton = new RadioButton( );
 rdoAppearanceButton.Parent = grpAppearance;
 rdoAppearanceButton.Text = "Button"; 
 rdoAppearanceButton.Location = new Point(10, 15 + yDelta);
 rdoAppearanceButton.CheckedChanged += 
 new System.EventHandler(rdoAppearance_CheckedChanged);
 GroupBox grpCheckAlign = new GroupBox( );
 grpCheckAlign.Parent = this;
 grpCheckAlign.Text = "CheckAlign";
 grpCheckAlign.Location = new Point(175, 
 grpAppearance.Bottom + 25);
 grpCheckAlign.Size = new Size(150, yDelta * 3);
 rdoCheckAlignMiddleLeft = new RadioButton( );
 rdoCheckAlignMiddleLeft.Parent = grpCheckAlign;
 rdoCheckAlignMiddleLeft.Text = "Middle Left"; 
 rdoCheckAlignMiddleLeft.Tag = ContentAlignment.MiddleLeft;
 rdoCheckAlignMiddleLeft.Location = new Point(10, 15);
 rdoCheckAlignMiddleLeft.Checked = true;
 rdoCheckAlignMiddleLeft.CheckedChanged += 
 new System.EventHandler(rdoCheckAlign_CheckedChanged);
 rdoCheckAlignMiddleRight = new RadioButton( );
 rdoCheckAlignMiddleRight.Parent = grpCheckAlign;
 rdoCheckAlignMiddleRight.Text = "Middle Right"; 
 rdoCheckAlignMiddleRight.Tag = ContentAlignment.MiddleRight;
 rdoCheckAlignMiddleRight.Location = new Point(10, 15 + yDelta);
 rdoCheckAlignMiddleRight.CheckedChanged += 
 new System.EventHandler(rdoCheckAlign_CheckedChanged);
 GroupBox grpTextAlign = new GroupBox( );
 grpTextAlign.Parent = this;
 grpTextAlign.Text = "TextAlign";
 grpTextAlign.Location = new Point(175, 
 grpCheckAlign.Bottom + 25);
 grpTextAlign.Size = new Size(150, yDelta * 4);
 rdoTextAlignMiddleLeft = new RadioButton( );
 rdoTextAlignMiddleLeft.Parent = grpTextAlign;
 rdoTextAlignMiddleLeft.Text = "Middle Left"; 
 rdoTextAlignMiddleLeft.Tag = ContentAlignment.MiddleLeft;
 rdoTextAlignMiddleLeft.Location = new Point(10, 15);
 rdoTextAlignMiddleLeft.Checked = true;
 rdoTextAlignMiddleLeft.CheckedChanged += 
 new System.EventHandler(rdoTextAlign_CheckedChanged);
 rdoTextAlignMiddleRight = new RadioButton( );
 rdoTextAlignMiddleRight.Parent = grpTextAlign;
 rdoTextAlignMiddleRight.Text = "Middle Right"; 
 rdoTextAlignMiddleRight.Tag = ContentAlignment.MiddleRight;
 rdoTextAlignMiddleRight.Location = new Point(10, 15 + yDelta);
 rdoTextAlignMiddleRight.CheckedChanged += 
 new System.EventHandler(rdoTextAlign_CheckedChanged);
 rdoTextAlignMiddleCenter = new RadioButton( );
 rdoTextAlignMiddleCenter.Parent = grpTextAlign;
 rdoTextAlignMiddleCenter.Text = "Middle Center"; 
 rdoTextAlignMiddleCenter.Tag = ContentAlignment.MiddleCenter;
 rdoTextAlignMiddleCenter.Location = new Point(10, 
 15 + (2 * yDelta));
 rdoTextAlignMiddleCenter.CheckedChanged += 
 new System.EventHandler(rdoTextAlign_CheckedChanged);
 } // close for constructor
 static void Main( ) 
 Application.Run(new Containers( ));
 private void cb_CheckedChanged(object sender, EventArgs e)
 FontStyle fs = 0;
 for (int i = 0; i < pnl.Controls.Count; i++)
 CheckBox cb = (CheckBox)pnl.Controls[i];
 if (cb.Checked)
 fs |= (FontStyle)cb.Tag;
 lbl.Font = new Font(lbl.Font, fs);
 private void rdoAppearance_CheckedChanged(object sender, 
 EventArgs e)
 if (rdoAppearanceNormal.Checked)
 for (int i = 0; i < pnl.Controls.Count; i++)
 CheckBox cb = (CheckBox)pnl.Controls[i];
 cb.Appearance = Appearance.Normal;
 for (int i = 0; i < pnl.Controls.Count; i++)
 CheckBox cb = (CheckBox)pnl.Controls[i];
 cb.Appearance = Appearance.Button;
 private void rdoCheckAlign_CheckedChanged(object sender, 
 EventArgs e)
 RadioButton rdo = (RadioButton)sender;
 for (int i = 0; i < pnl.Controls.Count; i++)
 CheckBox cb = (CheckBox)pnl.Controls[i];
 cb.CheckAlign = (ContentAlignment)rdo.Tag;
 private void rdoTextAlign_CheckedChanged(object sender, EventArgs e)
 RadioButton rdo = (RadioButton)sender;
 for (int i = 0; i < pnl.Controls.Count; i++)
 CheckBox cb = (CheckBox)pnl.Controls[i];
 switch ((int)rdo.Tag)
 case (int)ContentAlignment.MiddleLeft : 
 cb.TextAlign = ContentAlignment.MiddleLeft;
 case (int)ContentAlignment.MiddleRight : 
 cb.TextAlign = ContentAlignment.MiddleRight;
 case (int)ContentAlignment.MiddleCenter : 
 cb.TextAlign = ContentAlignment.MiddleCenter;
 } // close for rdoTextAlign_CheckedChanged 
 } // close for form class
} // close form namespace

Example 13-2. Containers in VB.NET (Containers.vb)


Option Strict On
imports System
imports System.Drawing
imports System.Windows.Forms
namespace ProgrammingWinApps
 public class Containers : inherits Form
 dim lbl as Label
 dim pnl as Panel
 dim yDelta as integer
 dim rdoAppearanceNormal as RadioButton
 dim rdoAppearanceButton as RadioButton
 dim rdoCheckAlignMiddleLeft as RadioButton
 dim rdoCheckAlignMiddleRight as RadioButton
 dim rdoTextAlignMiddleLeft as RadioButton
 dim rdoTextAlignMiddleRight as RadioButton
 dim rdoTextAlignMiddleCenter as RadioButton
 dim theStyles as FontStyle( )
 public sub New( )
 Text = "Containers"
 Size = new Size(350,375)
 lbl = new Label( )
 lbl.Parent = me
 lbl.Text = "The quick brown fox..."
 lbl.Location = new Point(0,0)
 lbl.AutoSize = true
 lbl.BorderStyle = BorderStyle.Fixed3D
 yDelta = lbl.Height + 10
 ' get the FontStyle values into an array
 dim theEnum as new FontStyle( )
 theStyles = CType([Enum].GetValues( _
 theEnum.GetType( )), FontStyle( ))
 pnl = new Panel( )
 pnl.Parent = me
 pnl.Location = new Point(0, yDelta )
 pnl.Size = new Size(150, (theStyles.Length - 1) * yDelta)
 pnl.BorderStyle = BorderStyle.Fixed3D
 pnl.AutoScroll = true
 dim i as integer = 1
 dim style as FontStyle
 dim cb as CheckBox
 for each style in theStyles
 cb = new CheckBox( )
 cb.Location = new Point(25, (yDelta * (i - 1)) + 10)
 cb.Size = new Size(75,20)
 cb.Text = style.ToString( )
 cb.Tag = style
 AddHandler cb.CheckedChanged, AddressOf cb_CheckedChanged
 if cb.Text = "Regular" then
 cb.Checked = true
 end if
 i = i + 1
 dim grpAppearance as GroupBox = new GroupBox( )
 grpAppearance.Parent = me
 grpAppearance.Text = "Appearance"
 grpAppearance.Location = new Point(175,yDelta)
 grpAppearance.Size = new Size(150, yDelta * 3)
 rdoAppearanceNormal = new RadioButton( )
 rdoAppearanceNormal.Parent = grpAppearance
 rdoAppearanceNormal.Text = "Normal"
 rdoAppearanceNormal.Location = new Point(10, 15)
 rdoAppearanceNormal.Checked = true
 AddHandler rdoAppearanceNormal.CheckedChanged, _
 AddressOf rdoAppearance_CheckedChanged
 rdoAppearanceButton = new RadioButton( )
 rdoAppearanceButton.Parent = grpAppearance
 rdoAppearanceButton.Text = "Button"
 rdoAppearanceButton.Location = new Point(10, 15 + yDelta)
 AddHandler rdoAppearanceButton.CheckedChanged, _
 AddressOf rdoAppearance_CheckedChanged
 dim grpCheckAlign as GroupBox = new GroupBox( )
 grpCheckAlign.Parent = me
 grpCheckAlign.Text = "CheckAlign"
 grpCheckAlign.Location = new Point(175, _
 grpAppearance.Bottom + 25)
 grpCheckAlign.Size = new Size(150, yDelta * 3)
 rdoCheckAlignMiddleLeft = new RadioButton( )
 rdoCheckAlignMiddleLeft.Parent = grpCheckAlign
 rdoCheckAlignMiddleLeft.Text = "Middle Left"
 rdoCheckAlignMiddleLeft.Tag = ContentAlignment.MiddleLeft
 rdoCheckAlignMiddleLeft.Location = new Point(10, 15)
 rdoCheckAlignMiddleLeft.Checked = true
 AddHandler rdoCheckAlignMiddleLeft.CheckedChanged, _
 AddressOf rdoCheckAlign_CheckedChanged
 rdoCheckAlignMiddleRight = new RadioButton( )
 rdoCheckAlignMiddleRight.Parent = grpCheckAlign
 rdoCheckAlignMiddleRight.Text = "Middle Right"
 rdoCheckAlignMiddleRight.Tag = ContentAlignment.MiddleRight
 rdoCheckAlignMiddleRight.Location = new Point(10, 15 + yDelta)
 AddHandler rdoCheckAlignMiddleRight.CheckedChanged, _
 AddressOf rdoCheckAlign_CheckedChanged
 dim grpTextAlign as GroupBox = new GroupBox( )
 grpTextAlign.Parent = me
 grpTextAlign.Text = "TextAlign"
 grpTextAlign.Location = new Point(175, grpCheckAlign.Bottom + 25)
 grpTextAlign.Size = new Size(150, yDelta * 4)
 rdoTextAlignMiddleLeft = new RadioButton( )
 rdoTextAlignMiddleLeft.Parent = grpTextAlign
 rdoTextAlignMiddleLeft.Text = "Middle Left"
 rdoTextAlignMiddleLeft.Tag = ContentAlignment.MiddleLeft
 rdoTextAlignMiddleLeft.Location = new Point(10, 15)
 rdoTextAlignMiddleLeft.Checked = true
 AddHandler rdoTextAlignMiddleLeft.CheckedChanged, _
 AddressOf rdoTextAlign_CheckedChanged
 rdoTextAlignMiddleRight = new RadioButton( )
 rdoTextAlignMiddleRight.Parent = grpTextAlign
 rdoTextAlignMiddleRight.Text = "Middle Right"
 rdoTextAlignMiddleRight.Tag = ContentAlignment.MiddleRight
 rdoTextAlignMiddleRight.Location = new Point(10, 15 + yDelta)
 AddHandler rdoTextAlignMiddleRight.CheckedChanged, _
 AddressOf rdoTextAlign_CheckedChanged
 rdoTextAlignMiddleCenter = new RadioButton( )
 rdoTextAlignMiddleCenter.Parent = grpTextAlign
 rdoTextAlignMiddleCenter.Text = "Middle Center"
 rdoTextAlignMiddleCenter.Tag = ContentAlignment.MiddleCenter
 rdoTextAlignMiddleCenter.Location = new Point(10, _
 15 + (2 * yDelta))
 AddHandler rdoTextAlignMiddleCenter.CheckedChanged, _
 AddressOf rdoTextAlign_CheckedChanged
 end sub ' close for constructor
 public shared sub Main( ) 
 Application.Run(new Containers( ))
 end sub
 private sub cb_CheckedChanged(ByVal sender as object, _
 ByVal e as EventArgs)
 dim fs as FontStyle = 0
 dim i as integer
 for i = 0 to pnl.Controls.Count - 1
 dim cb as CheckBox = CType(pnl.Controls(i), CheckBox)
 if cb.Checked then
 fs = fs or CType(cb.Tag, FontStyle)
 end if
 lbl.Font = new Font(lbl.Font, fs)
 end sub
 private sub rdoAppearance_CheckedChanged(ByVal sender as object, _
 ByVal e as EventArgs)
 dim i as integer
 if rdoAppearanceNormal.Checked then
 for i = 0 to pnl.Controls.Count - 1
 dim cb as CheckBox = CType(pnl.Controls(i), CheckBox)
 cb.Appearance = Appearance.Normal
 for i = 0 to pnl.Controls.Count - 1
 dim cb as CheckBox = CType(pnl.Controls(i), CheckBox)
 cb.Appearance = Appearance.Button
 end if
 end sub
 private sub rdoCheckAlign_CheckedChanged(ByVal sender as object, _
 ByVal e as EventArgs)
 dim rdo as RadioButton = CType(sender, RadioButton)
 dim i as integer
 for i = 0 to pnl.Controls.Count - 1
 dim cb as CheckBox = CType(pnl.Controls(i), CheckBox)
 cb.CheckAlign = CType(rdo.Tag, ContentAlignment)
 end sub
 private sub rdoTextAlign_CheckedChanged(ByVal sender as object, _
 ByVal e as EventArgs)
 dim rdo as RadioButton = CType(sender, RadioButton)
 dim i as integer
 for i = 0 to pnl.Controls.Count - 1
 dim cb as CheckBox = CType(pnl.Controls(i), CheckBox)
 select case rdo.Tag 
 case ContentAlignment.MiddleLeft 
 cb.TextAlign = ContentAlignment.MiddleLeft
 case ContentAlignment.MiddleRight 
 cb.TextAlign = ContentAlignment.MiddleRight
 case ContentAlignment.MiddleCenter 
 cb.TextAlign = ContentAlignment.MiddleCenter
 end select
 end sub 
 end class
end namespace

The Panel control was made too short by modifying the line of code that calculates and sets the Size property. In the version in the previous chapter, the vertical size was based on the Length property of the Styles array plus 1. In the following examples, the vertical size is minus 1. The BorderStyle property is set to Fixed3D, so you can see the outline of the panel, and the AutoScale property is set to true:


pnl.Size = new Size(150, (theStyles.Length - 1) * yDelta);
pnl.BorderStyle = BorderStyle.Fixed3D;
pnl.AutoScroll = true;


pnl.Size = new Size(150, (theStyles.Length - 1) * yDelta)
pnl.BorderStyle = BorderStyle.Fixed3D
pnl.AutoScroll = true

By setting the AutoScale property to true, either or both a vertical and horizontal scrollbar will appear, if necessary. In this example, only the vertical scrollbar was necessary.

The other change made in these examples is inside the iteration that generates the CheckBox controls in the panel. The versions of the programs in Chapter 11 added each checkbox to the panel with the following line of code:

cb.Parent = pnl

These examples use the Add method to add each checkbox to the Controls collection of the Panel control.


The result is the same either way.

There is no need to repeat how radio buttons and checkboxes work. Note, however, that the group box control makes each set of radio buttons independent and mutually exclusive within its set.

Windows Forms and the .NET Framework

Getting Started

Visual Studio .NET


Windows Forms

Dialog Boxes

Controls: The Base Class

Mouse Interaction

Text and Fonts

Drawing and GDI+

Labels and Buttons

Text Controls

Other Basic Controls

TreeView and ListView

List Controls

Date and Time Controls

Custom Controls

Menus and Bars


Updating ADO.NET

Exceptions and Debugging

Configuration and Deployment

Programming. NET Windows Applications
Programming .Net Windows Applications
ISBN: 0596003218
EAN: 2147483647
Year: 2003
Pages: 148 © 2008-2020.
If you may any questions please contact us: