Is there a way to manipulate the appearance of the individual buttons
in a TRadioGroup?
This subject falls into the yeah, it's something you could do, but should you
category. In other words, don't do it just because it's possible. Especially because for
what I'll be discussing here, this is pretty much undocumented stuff, and purposely hidden
from obvious access.
The Delphi engineers hid a lot of stuff from the visible interface for a good reason:
Unless you really know what you're doing and understand the workings of Delphi and the VCL
components and its object hierarchy, it's better to leave the internal stuff alone. In
fact, I'd venture that 98% of the time you won't need to access any of the hidden
features of Delphi. But as we all know, it's that remaining 2% that always kills us. I ran
into one of those 2% situations recently.
I had created a form that had a few TRadioGroups with up to 20 items in each on it. The
selections specified some standard query selection criteria, which my users could then
just set with a few clicks of the mouse, press the OK button and the program would
produce a formatted report. No possible mistyping, so no worries about entering in wrong
information for the criteria-matching. However, one of my users had a problem with the
form in that because the radio groups were side-by-side, it was difficult to immediately
tell which selection she had made from one group to the next. So she asked me if I could
change the appearance of the item she checked.
So what I did was take advantage of the fact that objects that can act as containers
all have an array property called Components, which holds the component index of a
contained component relative to the container. TRadioGroup is nothing more than a
TWinControl descendant (a few levels down) with a collection of TRadioButtons. And
conveniently, the radio buttons in the group are indexed with the ItemIndex property,
which in turn corresponds to the index of the Components array. So all we have to do to
access an individual TRadioButton in a TRadioGroup is to typecast a Components element as
a TRadioButton. What I came up with is fairly simple, but remember, this is undocumented
stuff.
Let's look at the code:
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Spin;
type
TForm1 = class(TForm)
RadioGroup1: TRadioGroup;
procedure FormCreate(Sender: TObject);
procedure RadioGroup1Click(Sender: TObject);
private
{ Private declarations }
OldItemIndex : Integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
OldItemIndex := -1;
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
with RadioGroup1 do begin
{if there was a previously set item, change it back to the
default appearance first.}
if (OldItemIndex > -1) then
with (Components[OldItemIndex] as TRadioButton) do begin
Color := clBtnFace;
Font.Color := clBtnFace;
Font.Style := [];
end;
{Now with the currently selected item, change its appearance.}
with (Components[ItemIndex] as TRadioButton) do begin
Color := clBlue;
Font.Color := clWhite;
Font.Style := [fsBold];
OldItemIndex := ItemIndex;
end;
end;
end;
The unit code above depicts a simple form with a single TRadioGroup dropped on it. I
filled the group up with about 20 values by hand for testing. Now what goes on is pretty
straightforward. I have defined a private variable called OldItemIndex that holds the
value of a previously selected item. This is a "just in case" thing in that if
users change their mind about a selection, they can go back to the radio group, change the
value, and the old item will revert back to its original appearance. The code is listed in
the OnClick handler for RadioGroup1 above.
Granted, this was pretty simple. You could do more with the TRadioButton if you wish.
In fact, all the properties of TRadioButton are available. But as I said before, this is
undocumented material, so use at your own risk, even if it's for a purpose as innocuous as
this.
Copyright © 1995, 1996, 1997 Brendan V. Delumpa All Rights Reserved
|