A family of components for which we have probably seen the largest number of VCL controls available over the years has been the so-called Outlook Sidebar family, mimicking the well established interface that was originally introduced by the Microsoft email program.
In modern applications, styles have changed a lot from the original collection of large icons used for the various sections of the program, but the usage of a sidebar with options and commands continues. For the first time, Delphi 2009 offers a similar component out of the box.
The CategoryPanelGroup control is a visual container of CategoryPanel controls. You create these category panels using the shortcut menu of the CategoryPanelGroup at design time or calling its CreatePanel method at runtime. The individual CategoryPanels refer to the container using the PanelGroup property, while the grouping controls has a Panel property (a bare-bones TList of pointers) or a list of child controls, in the standard Controls property.
If you try adding any other control directly to the CategoryPanelGroup the IDE will show the error "Only CategoryPanels can be inserted into a CategoryPanelGroupOf course, once you've defined a few CategoryPanels you can add virtually any control you like to them. Here is the user interface of this control, taken from the CategoryPanels demo:
123 Once more, you can refer to my Delphi 2007 Handbook for more information about these controls. Sorry to keep referring to my previous book, but there is little public information covering these controls... and my previous book really complements this one.
Buttons | [ Button4
The grouping control and the individual panels have a plethora of properties which you can use to customize the user interface, managing headers with multiple images depending on their collapsed or expanded status, activate gradient backgrounds for the headers, change the font and the Chevron colors, and much more.
These are the settings of the panels above (from which I've removed details of the hosted controls):
object CategoryPanelGroup1: TCategoryPanelGroup VertScrollBar.Tracking = True HeaderFont.Color = clWindowText HeaderFont.Name = 'Tahoma' Images = ImageList1
object CategoryPanel1: TCategoryPanel Caption = 'CategoryPaneH' CollapsedImageIndex = 0 ExpandedImageIndex = 0 object Button1: TButton... object Button2: TButton... end object CategoryPanel2: TCategoryPanel Caption = 'CategoryPaneT2' Collapsed = True CollapsedImageIndex = 2 ExpandedImageIndex = 1 object CheckBox1: TCheckBox... object CheckBox2: TCheckBox... object CheckBox3: TCheckBox... end object CategoryPanel3: TCategoryPanel Caption = 'CategoryPanel3' object GridPanel1: TGridPanel Align = alClient Caption = 'GridPaneH' ControlCollection = <...> ShowCaption = False object Button3: TButton... object Button4: TButton... object Button5: TButton... object Button6: TButton...
end end end
If we look at the header images, the first panel uses the same one for both states, the second uses two different images for the expanded and collapsed states, while the third has no custom images and uses the default Chevron symbol. The third CategoryPanel doesn't host its controls directly, but has a GridPanel (with 4 buttons) aligned to its entire surface. This is an example of how you can combine a CategoryPanel with panels providing custom positioning. The program has a little code as well. A first button is used to add a new dynamic CategoryPanel to the group and place a button over it:
Sender: TObject); var newPanel: TCategoryPanel; begi n newPanel := CategoryPanelGroup1.CreatePanel(self)
as TCategoryPanel; NewPanel.Caption := 'Dynamic Panel'; with TButton.Create(self) do begi n
Caption := 'New button'; Parent := NewPanel; SetBounds (10, 10, Width, Height);
Notice that the CreatePanel method of the category panel group control returns a generic TCustomCategoryPanel, so I had to cast the type to the specific TCategoryPanel type to refer to the Caption property. The reason for this apparently strange behavior is that the category panel group control creates an object of a class which you can configure in an inherited class by overriding the GetCategoryPanelClass virtual function. Still, this is a little unusual, as most other VCL controls that let you customize the class of an internal object refer to a specific class and not a partially defined base class as in this case. This approach apparently makes the control more customizable, as you can have a different implementation class not exposing some of the base class properties, but it also makes code that assumes the given type (and you have to assume a type to be able to use the individual panels, as in the code above) quite error prone. The code above will fail in case of a different category panel class.
A second button shows the two different ways to list the existing category panels of a group that I mentioned earlier, the generic Controls array or the specific (but less type safe) Panels property. The former, in fact, is an array of controls, while the latter is a list of pointers124:
Sender: TObject); var
I: Integer; begi n
for I := 0 to CategoryPanelGroup1.ControlCount - 1 do ListBox1.Items.Add (
(CategoryPanelGroup1.Controls[I] as TCategoryPanel). Caption);
for I := 0 to CategoryPanelGroup1.Panels.Count - 1 do ListBox1.Items.Add (
Was this article helpful?
What you need to know about… Project Management Made Easy! Project management consists of more than just a large building project and can encompass small projects as well. No matter what the size of your project, you need to have some sort of project management. How you manage your project has everything to do with its outcome.