activation désactivation "event"
Bonjour
Ayant souvent besoin de désactiver un événement d'un composant dans le programme qui occupe la majeure partie de mon temps, j'ai voulu simplifier la chose.
Pour ne plus être obligé dans chaque procédure de déclarer un TNotifyEvent et l'utiliser pour lui assigner l'événement ciblé, mettre l'événement à nil, faire mon opération et réassigner l'événement au composant, j'ai écris vite fait le code suivant:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
unit UEventManager;
interface
uses System.SysUtils, System.Classes, System.StrUtils, System.Generics.Collections,
System.Rtti,
FMX.Controls, FMX.StdCtrls, FMX.Listbox, FMX.Edit,
EditNumerique;
type
TEventManager = class(TObject)
private
Events: TDictionary<TControl, TNotifyEvent>;
protected
public
constructor Create;
destructor Destroy; override;
procedure EnableEvent(Ct: TControl);
procedure DisableEvent(Ct: TControl);
function IsEnabled(Ct: TControl): Boolean;
function IsDisabled(Ct: TControl): Boolean;
end;
var
EvtMgr: TEventManager;
implementation
{ TEventManager }
constructor TEventManager.Create;
begin
inherited Create;
Events := TDictionary<TControl, TNotifyEvent>.Create;
end;
destructor TEventManager.Destroy;
begin
Events.Clear;
FreeAndNil(Events);
inherited;
end;
const
Props: array[0..1] of string = ('OnChange', 'OnClick');
procedure TEventManager.DisableEvent(Ct: TControl);
var
P: TPair<TControl, TNotifyEvent>;
begin
// On ne peut pas désactiver un évènement déjà désactivé
if Events.ContainsKey(Ct) then
Exit;
if Ct is TCheckBox then
begin
Events.Add(Ct, TCheckBox(Ct).OnClick);
TCheckBox(Ct).OnClick := nil;
end
else if Ct is TComboBox then
begin
Events.Add(Ct, TComboBox(Ct).OnChange);
TComboBox(Ct).OnChange := nil;
end
else if Ct is TEdit then
begin
Events.Add(Ct, TEdit(Ct).OnChange);
TEdit(Ct).OnChange := nil;
end
else if Ct is TEditNumeric then
begin
Events.Add(Ct, TEditNumeric(Ct).OnChange);
TEditNumeric(Ct).OnChange := nil;
end;
end;
procedure TEventManager.EnableEvent(Ct: TControl);
var
P: TPair<TControl, TNotifyEvent>;
Prt: TRttiProperty;
S: string;
begin
if Events.ContainsKey(Ct) then
begin
P := Events.ExtractPair(Ct);
if Ct is TCheckBox then
TCheckBox(Ct).OnClick := P.Value
else if Ct is TComboBox then
TComboBox(Ct).OnChange := P.Value
else if Ct is TRadioButton then
TRadioButton(Ct).OnChange := P.Value
else if Ct is TEdit then
TEdit(Ct).OnChange := P.Value
else if Ct is TEditNumeric then
TEditNumeric(Ct).OnChange := P.Value;
end;
end;
function TEventManager.IsDisabled(Ct: TControl): Boolean;
begin
Result := Events.ContainsKey(Ct);
end;
function TEventManager.IsEnabled(Ct: TControl): Boolean;
begin
Result := not Events.ContainsKey(Ct);
end;
initialization
EvtMgr := TEventManager.Create;
finalization
FreeAndNil(EvtMgr);
end. |
et il s'utilise tout simplement comme ça:
Code:
1 2 3 4
|
UEventManager.EvtMgr.DisableEvent(EditAdd);
// .....
UEventManager.EvtMgr.EnableEvent(EditAdd); |
ça fonctionne très bien et ça demanderait surement quelques améliorations mais pour le moment ça me suffit.
Mais comme vous le voyez, le côté "générique" n'y est pas vraiment.
Comment je pourrais améliorer ça pour ne pas avoir à rajouter un test sur le type de classe si je devais prendre en compte d'autres types que ceux que j'ai inclus ?
Evidemment, si l'idée de ce bout de code vous séduit, n'hésitez pas à l'utiliser ;)