Question

Dans une partie de l'application que je travaille, il y a un contrôle de forme qui fait la validation à la réception du message CMExit, ce qui est exactement la documentation Delphi dit de le faire (cet exemple de code est de la Delphi fichiers):

procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
 try
  FDataLink.UpdateRecord;                          { tell data link to update database }
 except
  on Exception do SetFocus;                      { if it failed, don't let focus leave }
 end;
 inherited;
end;

Le but est d'effectuer la validation dès que le contrôle perd le focus. Ainsi, par exemple, si je devais cliquer sur le bouton OK, le contrôle de forme serait perdre le focus, cette méthode courir et à une exception fixerait le focus à ce contrôle de formulaire. (Ainsi, l'événement « click » sur le bouton OK ne serait jamais passer par la boîte de dialogue et ne fermerait jamais).

Le problème que je vais avoir est que ce contrôle de formulaire est à l'intérieur d'une fenêtre de dialogue modale. En cliquant sur OK n'envoyer le message en effet CMExit et provoque l'enregistrement à mettre à jour (et la validation de se produire). Cependant, tout en appuyant sur Entrée dans le contrôle de la forme provoque la boîte de dialogue modale fermer sans envoyer le message CMExit . Il est comme si le contrôle de formulaire ne « perd le focus ». Cela signifie que non seulement la fin de dialogue sans la forme validant réellement les données, mais l'ensemble de données ne sont pas mis à jour,.

Compte tenu de ce problème, où est le meilleur endroit pour moi de placer ma mise à jour du jeu de données / code de validation? Je pouvais déplacer jusqu'à la forme de dialogue lui-même et la mettre en œuvre dans le gestionnaire OnCloseQuery, mais cela signifierait que la logique est dupliqué à la fois le contrôle de forme et sur la forme elle-même. (Le contrôle de formulaire est utilisé dans d'autres endroits, et je veux éviter de changer son comportement).

(je spécule que CMExit ne se déclenche pas parce que le contrôle n'a jamais vraiment ne perdre le focus. La forme est fermée, mais le contrôle de la forme « a le focus » toujours sur la forme fermée.)

Était-ce utile?

La solution

Fermeture d'une forme ne se déclenche pas nécessairement l'événement en sortie d'un TControl. L'utilisateur pourrait frapper Alt-F4, par exemple.

Je vous suggère de déplacer la validation à un proc séparé, et appelle cela proc séparé à la fois la sortie sur et sur les événements proches.

Le code ci-dessous devrait fonctionner sans trop de modification:

function TDBCalendar.UpdateSuccessful: boolean;
begin
  { tell data link to update database }
  { if successful, return True, else return False }
  { this function must be Public if a form is gonna check this value }
  Result := True;
  try
    FDataLink.UpdateRecord;
  except on Exception do
    Result := False;
  end;
  inherited;
end;

procedure TDBCalendar.CMExit(var Message: TWMNoParams);
begin
  //if not valid, then don't let them leave
  if not(UpdateSuccessful) then begin
    SetFocus;
  end;
end;

///////////////////////////////////////////
//on the form that contains your control...
///////////////////////////////////////////

procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //if not valid, then don't let them close the form
  if not(dbcal.ControlIsValid) then begin
    Action := caNone;
  end
  else begin
    inherited;
  end;
end;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top