Programmer un BeginUpdate/EndUpdate pour bloquer des evenements dans un composant


Contenu du snippet

Démonstration de l'élaboration d'un système de mise a jours des données
d'un composant, permettant l'arrêt des méthodes ou évènements appelés 
a chaque action sur ces données.
Pratique pour les Listes et Collections par exemple, usitée dans la classe TStrings, 
ou elle permet de bloquer l'évènement OnChange qui est appelé 
a chaque Add, Append, Delete, Exchange etc.

{ interface }

Type
  { Remarque : en général vous introduirez directement le code ci-dessous
    dans votre composant. }
  TUpdateControl = class(TObject) 
  private
    { compteur d'appel a BeginUpdate/EndUpdate }
    fUpdateCount : integer;
    { "reader" pour la propriété UpdateState }
    function  GetUpdateState : boolean;
  protected
    { methode abstraite a surcharger pour adapter TUpdateControl a vos besoins }
    procedure SetUpdateState(const Updating: Boolean); virtual; abstract;
  public
    constructor Create; //override; si besoin
    { debut de la mise a jours, doit etre suivie par un Try...Finally }
    procedure BeginUpdate;
    { fin de la mise a jours, doit figurer dans le Finally }
    procedure EndUpdate;
    { propriété permettant de connaitre l'etat de la mise a jours }
    property UpdateState : boolean read GetUpdateState;
  end;

{ implementation }

{ TUpdateControl }

constructor TUpdateControl.Create;
begin
  // inherited Create; si besoin
  {mise a zero du compteur de mise a jours }
  fUpdateCount := 0;
end;

procedure TUpdateControl.BeginUpdate;
begin
  { appel SetUpdateState avec True si on part de 0 }
  if fUpdateCount = 0 then
     SetUpdateState(True);
  { incremente le compteur de mise a jours }
  fUpdateCount := fUpdateCount + 1;
end;

procedure TUpdateControl.EndUpdate;
begin
  { decremente le compteur de mise a jours }
  fUpdateCount := fUpdateCount - 1;
  { appel SetUpdateState avec False si on reviens a 0 }
  if fUpdateCount = 0 then
     SetUpdateState(False);
end;

function TUpdateControl.GetUpdateState : boolean;
begin
  { renvois True si fUpdateCount est different de 0
    ce qui sous entend qu'il y a deja eu un appel
    a l'une des methode BeginUpdate ou EndUpdate }
  result := fUpdateCount <> 0;
end;
   
Il ne reste plus qu'a interroger la propriété UpdateState pour savoir si une méthode
ou un évènement ne doit plus être exécuter tant que la mise a jours est en cours,
exemple d'utilisation dans votre composant :

procedure AppelEvenement;
begin
  { arrête la méthode si le composant est en cours de mise a jours }
  if UpdateState then
    Exit;
  
  { ce code ne serat pas exécuter si UpdateState est a True }
  if Assigned(fEvenement) then
    fEvenement(arguments);
end;

Note : n'oubliez pas que BeginUpdate et EndUpdate s'appellent comme ceci dans
votre programme :

procedure Methode;
begin
  { S'utilise dans un bloc Try...Finally pour s'assurer de decrementation
    du compteur de mise a jours. }
   MonComposant.BeginUpdate;
  Try
    { code }
  Finally
    MonComposant.EndUpdate;
  end;
end;



Compatibilité : Delphi 5

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.