Containers

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.

Tip

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.

Containers

Figure 13-2. Containers

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

image with no caption

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(  );
            pnl.Controls.Add(cb);
            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 
               System.EventHandler(cb_CheckedChanged);
            if (cb.Text =  = "Regular")
               cb.Checked = true;
            i++;
         }
   
         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;
            }
         }
         else
         {
            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;
                  break;
               case (int)ContentAlignment.MiddleRight : 
                  cb.TextAlign = ContentAlignment.MiddleRight;
                  break;
               case (int)ContentAlignment.MiddleCenter : 
                  cb.TextAlign = ContentAlignment.MiddleCenter;
                  break;
            }
         }
      }   //  close for rdoTextAlign_CheckedChanged 
   }      //  close for form class
}         //  close form namespace

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

image with no caption

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(  )
            pnl.Controls.Add(cb)
            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
         next
   
         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
         next
         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
            next
         else
            for i = 0 to pnl.Controls.Count - 1
               dim cb as CheckBox = CType(pnl.Controls(i), CheckBox)
               cb.Appearance = Appearance.Button
            next
         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)
         next
      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
         next
      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:

image with no caption

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

image with no caption

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.

pnl.Controls.Add(cb)

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset