Gehe zu deutscher Webseite

ViaThinkSoft CodeLib

This article is in:
CodeLibProgramming aidsDelphi

Problem:

Bei dem Scrolling wird zuerst Cancel und dann erst OnBeforeScroll aufgerufen

Lösung:

Der Speichern-Dialog soll also bereits im OnBeforeCancel angezeigt werden. Damit dieser Dialog aber nicht beim Bewussten speichern auftritt (Cancel-Button), soll bei diesem Cancel-Button ein .Tag gesetzt werden, der dem OnBeforeCancel mitteilt, dass kein Dialog angezeigt werden soll.

Dies hat auch den Vorteil, dass man nun nicht bei den gelben Suchhänden oder dem FormOnCloseQuery keinen Abfragedialog mehr benötigt, da Cancel bei jeder Art von Scrolling/Filterung aufgerufen wird!

Im FormOnCloseQuery muss nun nur noch folgendes durchgeführt werden:

if (Table1.state in [dsEdit, dsInsert]) then Table1.Cancel;

Der komplette Code:


procedure TForm1.Table1BeforeCancel(DataSet: TDataSet);
var
  abfrage: Integer;
begin
  // Tag 1 = Es wurde der "Abbrechen"-Knopf im DBNavigator gedrückt, also wollen wir keine unnötige Bestätigung
  // Alles andere = Irgendwas anderes (z.B. Scrolling oder versehentlich versucht das Fenster zu schließen)
  if Table1.Tag = 1 then exit;

  abfrage := MessageDlg('Speichern?', mtConfirmation, mbYesNoCancel, 0);

  if (abfrage = IDNo) or (abfrage = IDYes) or (abfrage = IDOK) then
  begin
     if abfrage = IDYes then
     begin
       if (Table1.state in [dsEdit, dsInsert]) then Table1.Post;
     end;
     if abfrage = IDNo then
     begin
       // Wir befinden uns bereits in Table1.Cancel, daher auskommentiert.
       // if (Table1.state in [dsEdit, dsInsert]) then Table1.Cancel;
     end;
  end
  else raise EAbort.Create('Abbruch durch Benutzer'); // Cancel geklickt
end;

procedure TForm1.DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn);
begin
  if Button = nbCancel then
  begin
    if Table1.state  in [dsEdit,dsInsert] then
    begin
      // Tag=1 soll verhindern, dass nicht gefragt wird, ob man Speichern möchte.
      // Ansonsten würde diese Meldung kommen, denn ".Cancel" wird automatisch
      // bei Ereignissen wie z.B. dem Scrolling aufgerufen (noch bevor
      // OnBeforeScroll aufgerufen wird), bei dem man einen Abfragedialog wünscht.
      Table1.Tag := 1;
      try
        Table1.Cancel;
      finally
        Table1.Tag := 0;
      end
    end;
  end;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Table1.Cancel;
end;
Daniel Marschall
ViaThinkSoft Co-Founder