Author: Tomas Rutkauskas
Is there a clean, simple solution to this problem: You have three RadioGroups: RgA,
RgB, and RgC. Each has the same three items (numbered 0, 1, and 2 - actual string
values are irrelevant here). Initially, RgA.ItemIndex = 0, RgB.ItemIndex = 1, and
RgC.ItemIndex =2. The problem is to ensure that each selection (ItemIndex) is
unique across all the RadioGroups. If the user clicks RgA and changes its index to
2, RgC's ItemIndex must change to 0 (the unused value). You'll always have one
RadioGroup with an ItemIndex of 0, one with 1, and one with 2.
Answer:
Here is a possible approach:
1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 Menus, StdCtrls, ExtCtrls;
8
9 type
10 TForm1 = class(TForm)
11 RadioGroup1: TRadioGroup;
12 RadioGroup2: TRadioGroup;
13 RadioGroup3: TRadioGroup;
14 procedure FormCreate(Sender: TObject);
15 procedure AllRadiogroupsClick(Sender: TObject);
16 private
17 { Private declarations }
18 FRGroups: array[1..3] of TRadioGroup;
19 FRGroupItemIndices: array[1..3] of 0..2;
20 public
21 { Public declarations }
22 end;
23
24 var
25 Form1: TForm1;
26
27 implementation
28
29 {$R *.DFM}
30
31 procedure TForm1.FormCreate(Sender: TObject);
32 var
33 i: Integer;
34 begin
35 FRGroups[1] := RadioGroup1;
36 FRGroups[2] := RadioGroup2;
37 FRGroups[3] := RadioGroup3;
38 for i := 1 to 3 do
39 begin
40 FRGroupItemIndices[i] := FRGroups[i].ItemIndex;
41 FRGroups[i].Tag := i;
42 end;
43 { assumes indices have been set up correctly at design time! }
44 end;
45
46 procedure TForm1.AllRadiogroupsClick(Sender: TObject);
47 var
48 oldvalue: Integer;
49 swapWith: Integer;
50 thisGroup: TRadioGroup;
51
52 function FindOldValue(value: Integer): Integer;
53 var
54 i: integer;
55 begin
56 result := 0;
57 for i := 1 to 3 do
58 if FRGroupItemIndices[i] = value then
59 begin
60 result := i;
61 break;
62 end;
63 if result = 0 then
64 raise exception.create('Error in FindOldValue');
65 end;
66
67 begin
68 {Tag property of radiogroup stores index for arrays}
69 {Find old value of the group that changed}
70 thisGroup := Sender as TRadioGroup;
71 oldvalue := FRGroupItemIndices[thisGroup.Tag];
72 if oldvalue = thisGroup.ItemIndex then
73 Exit;
74 {Find the index of the group that currently has the value this group changed to}
75 swapWith := FindOldValue(thisGroup.ItemIndex);
76 {Change the array values}
77 FRGroupItemIndices[thisGroup.Tag] := thisGroup.ItemIndex;
78 FRGroupItemIndices[swapWith] := Oldvalue;
79 {Change the Itemindex of the other group. Disconnect handler while doing so}
80 with FRGroups[swapWith] do
81 begin
82 OnClick := nil;
83 ItemIndex := oldValue;
84 OnClick := AllRadioGroupsClick;
85 end;
86 end;
87
88 end.
|