Title: Take the enabling/disabling to a higher level
Question: When your form is full of
if myCheckBox.checked then
myControl.Enabled;
Answer:
Take the enabling/disabling to a higher level.
First part is to create a series of classes which control the enabling and disabling. The controls to be affected must be registered with a controller class which is responsible for managing everything.
Here is the controller classes:
unit cls_GUIController;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, stdctrls;
type
TControlLink = class
protected
FMasterControl : TControl;
FSlaveControlsToEnable : TList;
FSlaveControlsToDisable : TList;
public
constructor Create(pMasterControl : TControl; pSlaveControlsToEnable, pSlaveControlsToDiable : array of TControl); virtual;
destructor Destroy(); override;
procedure ChangeState; virtual; abstract;
property MasterControl : TControl read FMasterControl;
property SlaveControlsToEnable : TList read FSlaveControlsToEnable;
property SlaveControlsToDisable : TList read FSlaveControlsToDisable;
end;//TControllLink
type
TCheckBoxControlLink = class(TControlLink)
protected
procedure ChangeState; override;
end;//TCheckBoxControlLink
type
TGUIController = class
protected
FControlable : TList;
function Matches(pMasterControl : TControl) : TControlLink; virtual;
function FindMasterControl(pMasterControl : TObject) : TControlLink; virtual;
public
constructor Create; virtual;
destructor Destroy(); override;
procedure ControlHasChanged(Sender : TObject); virtual;
procedure RegisterControls(pControlLink : TControlLink); virtual;
end; //TGUIController
implementation
(****************** TControlLink *******************)
constructor TControlLink.Create(pMasterControl: TControl; pSlaveControlsToEnable, pSlaveControlsToDiable : array of TControl);
var
vNumber : Integer;
begin
inherited Create;
FMasterControl := pMasterControl;
FSlaveControlsToEnable := TList.Create();
FSlaveControlsToDisable := TList.Create();
for vNumber := 0 to length(pSlaveControlsToEnable)-1 do
FSlaveControlsToEnable.Add(pSlaveControlsToEnable[vNumber]);
for vNumber := 0 to length(pSlaveControlsToDiable)-1 do
FSlaveControlsToDisable.Add(pSlaveControlsToDiable[vNumber]);
end;//Create
destructor TControlLink.Destroy();
begin
while FSlaveControlsToEnable.Count 0 do
FSlaveControlsToEnable.Delete(0);
FSlaveControlsToEnable.Free;
while FSlaveControlsToDisable.Count 0 do
FSlaveControlsToDisable.Delete(0);
FSlaveControlsToDisable.Free;
end;//Destroy
(****************** TControlLink *******************)
(****************** TCheckBoxControlLink *******************)
procedure TCheckBoxControlLink.ChangeState;
var
vSlaves : Integer;
begin
if TCheckBox(MasterControl).Checked then
begin
for vSlaves := 0 to FSlaveControlsToEnable.Count -1 do
TControl(FSlaveControlsToEnable[vSlaves]).Enabled := True;
for vSlaves := 0 to FSlaveControlsToDisable.Count -1 do
TControl(FSlaveControlsToDisable[vSlaves]).Enabled := False;
end
else
begin
for vSlaves := 0 to FSlaveControlsToEnable.Count -1 do
TControl(FSlaveControlstoEnable[vSlaves]).Enabled := False;
for vSlaves := 0 to FSlaveControlsToDisable.Count -1 do
TControl(FSlaveControlsToDisable[vSlaves]).Enabled := True;
end;
end;//ChangeState
(****************** TCheckBoxControlLink *******************)
(****************** TGUIController *******************)
constructor TGUIController.Create ();
begin
FControlable := TList.Create();
inherited Create();
end;//Create
destructor TGUIController.Destroy();
begin
while FControlable.Count 0 do
FControlable.Delete(0);
FControlable.Free;
end;//Destory
procedure TGUIController.RegisterControls(pControlLink : TControlLink);
begin
FControlable.Add(pControlLink);
end; //RegisterControls
function TGUIController.FindMasterControl(pMasterControl : TObject) : TControlLink;
var
vControlLink : TControlLink;
begin
if pMasterControl is TControl then
begin
vControlLink := Matches(TControl(pMasterControl));
Result := vControlLink;
end//if
else
Result := nil;
end;//FindMasterControl
function TGUICOntroller.Matches(pMasterControl : TControl) : TControlLink;
var
vFound : Boolean;
vItem : Integer;
begin
vFound := False;
vItem := 0;
Result := nil;
while not(vFound) and (vItem begin
if pMasterControl = TControlLink(FControlable.Items[vItem]).MasterControl then
begin
vFound := True;
Result := FControlable.Items[vItem];
end;//if
Inc(vItem);
end;//while
end;
procedure TGUIController.ControlHasChanged(Sender : TObject);
var
vControlsToChange : TControlLink;
vCurrentItem : Integer;
begin
vControlsToChange := FindMasterControl(Sender);
if vControlsToChange = nil then
raise Exception.Create('Control not registered '+Sender.ClassName)
else
if Sender is TCustomCheckBox then
TCheckBoxControlLink(vControlsToChange).ChangeState;
end;//ControlHasChanged
(****************** TGUIController *******************)
end.
The form
unit OurForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ComCtrls, Mask, ToolEdit, OleServer, Excel97, Db,
DBTables, ExtCtrls, GIRComponents, Global, DBCtrls, SafeStoredProc,
Grids, DBGrids, cls_GUIController;
type
TOurForm = class(TForm)
private
{ Private declarations }
FGUIController : TGUIController;
end;
(* In the form create register the controls *)
procedure TOurForm.FormCreate(Sender: TObject);
begin
FGUIController := TGUIController.Create();
with FGUIController do
begin
RegisterControls(TCheckBoxControlLink.Create(chkTreat, [cbxTreaty], []));
RegisterControls(TCheckBoxControlLink.Create(chkMonthEnd, [cbxMonthEndDateStart,cbxMonthEndDateEnd], []));
RegisterControls(TCheckBoxControlLink.Create(chkPostedDate, [ebBeginPostedDate, ebEndPostedDate], []));
RegisterControls(TCheckBoxControlLink.Create(chkCheckDate, [ebBeginCheckDate, ebEndCheckDate], [chkDepositDate, ebBeginDepositDate, ebEndDepositDate]));
RegisterControls(TCheckBoxControlLink.Create(chkDepositDate, [ebBeginDepositDate, ebEndDepositDate],[chkCheckDate, ebBeginCheckDate, ebEndCheckDate] ));
end;
end;
(* Add this method *)
procedure TOurForm.ControlHasChanged(Sender: TObject);
begin
FGUIController.ControlHasChanged(Sender);
end;//ControlHasChanged
(* Then for each controls onClick event *)
Assign it to the ControlHasChanged method.
Then hey presto!!