How to get unique ItemIndexes across multiple TRadioGroups (Views: 711)
Problem/Question/Abstract: 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: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, ExtCtrls; type TForm1 = class(TForm) RadioGroup1: TRadioGroup; RadioGroup2: TRadioGroup; RadioGroup3: TRadioGroup; procedure FormCreate(Sender: TObject); procedure AllRadiogroupsClick(Sender: TObject); private { Private declarations } FRGroups: array[1..3] of TRadioGroup; FRGroupItemIndices: array[1..3] of 0..2; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin FRGroups[1] := RadioGroup1; FRGroups[2] := RadioGroup2; FRGroups[3] := RadioGroup3; for i := 1 to 3 do begin FRGroupItemIndices[i] := FRGroups[i].ItemIndex; FRGroups[i].Tag := i; end; { assumes indices have been set up correctly at design time! } end; procedure TForm1.AllRadiogroupsClick(Sender: TObject); var oldvalue: Integer; swapWith: Integer; thisGroup: TRadioGroup; function FindOldValue(value: Integer): Integer; var i: integer; begin result := 0; for i := 1 to 3 do if FRGroupItemIndices[i] = value then begin result := i; break; end; if result = 0 then raise exception.create('Error in FindOldValue'); end; begin {Tag property of radiogroup stores index for arrays} {Find old value of the group that changed} thisGroup := Sender as TRadioGroup; oldvalue := FRGroupItemIndices[thisGroup.Tag]; if oldvalue = thisGroup.ItemIndex then Exit; {Find the index of the group that currently has the value this group changed to} swapWith := FindOldValue(thisGroup.ItemIndex); {Change the array values} FRGroupItemIndices[thisGroup.Tag] := thisGroup.ItemIndex; FRGroupItemIndices[swapWith] := Oldvalue; {Change the Itemindex of the other group. Disconnect handler while doing so} with FRGroups[swapWith] do begin OnClick := nil; ItemIndex := oldValue; OnClick := AllRadioGroupsClick; end; end; end. |