Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TDataSet.Refresh erweitern (https://www.delphipraxis.net/187591-tdataset-refresh-erweitern.html)

ConnorMcLeod 12. Dez 2015 07:52

TDataSet.Refresh erweitern
 
Hallo Kollegen,
es geht darum, die Refresh-Methode von TDataSet zu erweitern von:

Delphi-Quellcode:
procedure TDataSet.Refresh;
begin
  DoBeforeRefresh;
  CheckBrowseMode;
  UpdateCursorPos;
  try
    InternalRefresh;
  finally
    Resync([]);
    DoAfterRefresh;
  end;
end;
nach

Delphi-Quellcode:
procedure TDataSet.Refresh;
begin

  if <Bedingung> then exit;

  DoBeforeRefresh;
  CheckBrowseMode;
  UpdateCursorPos;
  try
    InternalRefresh;
  finally
    Resync([]);
    DoAfterRefresh;
  end;
end;
Delphi verweigert mir das overload in einer abgeleiteten Klasse, mit class helpers bekommt man eine Endlosschleife und den Methodenzeiger umbiegen mit TMethod.Code funkt auch nicht. Da meint Delphi, daß es eine umgültige Typumwandlung sei.

Jemand ne Idee, wie man das gebacken bekommt?

nahpets 12. Dez 2015 12:00

AW: TDataSet.Refresh erweitern
 
Bin mir nicht sicher, aber Du meinst doch sowas:
Delphi-Quellcode:
unit DataSetTest;

interface

uses
  SysUtils, Classes, DB;

type
  tDataSetTest = class(TDataSet)
  private
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    procedure Refresh;
  published
    { Published-Deklarationen }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('WoAuchImmer', [tDataSetTest]);
end;

procedure tDataSetTest.Refresh;
begin
  if 1 = 2 then exit; // latürnich eine sinnvolle Bedingung ;-)
  inherited;
end;

end.
Delphi 7 kompiliert das und installiert die Komponente anstandslos.

Der schöne Günther 12. Dez 2015 12:22

AW: TDataSet.Refresh erweitern
 
Ich habe keine Ahnung was du genau vorhast, aber vielleicht kannst du ja auch das
Delphi-Quellcode:
BeforeRefresh
-Event nutzen und dort einfach nur
Delphi-Quellcode:
Abort()
sagen :stupid:

(Abort wird sogar als Beispiel für TDataSet.BeforePost angeführt)

ConnorMcLeod 12. Dez 2015 14:05

AW: TDataSet.Refresh erweitern
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1324204)
Ich habe keine Ahnung was du genau vorhast, aber vielleicht kannst du ja auch das
Delphi-Quellcode:
BeforeRefresh
-Event nutzen und dort einfach nur
Delphi-Quellcode:
Abort()
sagen :stupid:

(Abort wird sogar als Beispiel für TDataSet.BeforePost angeführt)

Danke für die Idee!
AFAIK springt Abort zum nächsten finally und beendet dann das Programm.
Wenn ich das BeforeRefresh überschreibe, dann kommt Refresh trotzdem in jedem Fall dran. Innerhalb von Refresh wird BeforeRefresh ausgeführt ...
danke trotzdem!

ConnorMcLeod 12. Dez 2015 14:12

AW: TDataSet.Refresh erweitern
 
Zitat:

Zitat von nahpets (Beitrag 1324199)
Bin mir nicht sicher, aber Du meinst doch sowas:
Delphi-Quellcode:
  public
    { Public-Deklarationen }
    procedure Refresh;

implementation

procedure tDataSetTest.Refresh;
begin
  if 1 = 2 then exit; // latürnich eine sinnvolle Bedingung ;-)
  inherited;
end;

Im Prinzip ja. Aber ... ich bräuchte zusätzlich noch etwas wie ein reintroduce, weil die Objekte während des Programmablaufes auch mal als TDataSet verwendet werden und nicht immer nur als tDataSetTest. Aber reintroduce greift nicht, sondern es kommt immer das Refresh von TDataSet dran. Deswegen wollte ich den Code auswechseln.

nahpets 12. Dez 2015 15:51

AW: TDataSet.Refresh erweitern
 
Zugegebenermaßen ist mir nicht klar, was Du möchtest.

Versuch einer Erklärung:

Du möchtest ein TDataSet verwenden und von dem die Methode Refresh in einer veränderten Form (bzw. nur unter bestimmten Bedingungen nutzen), ohne einen Nachkommen von TDataSet zu erstellen, der über eine veränderte Methode Refresh verfügt.

Zeig uns doch bitte mal die Routine aus Deinem Quelltext, an der Refresh aufgerufen werden soll. Eventuell fällt ja jemandem eine Möglichkeit ein, dort entsprechend Deinen Wünschen zu reagieren.

Oder hast Du keinen Einfluß auf den Aufruf von Refresh, möchtest aber trotzdem ein verändertes Verhalten erreichen?

Mir fällt jetzt eigentlich nur ein, wie oben bereits vorgeschlagen, onBeforeRefresh zu nutzen, dort die Bedingung zu prüfen und, falls diese nicht erfüllt ist, eine Exception zu werfen, damit TDataSet.Refresh nicht aufgerufen wird. Aber dann benötigst Du auch eine Fehlerbehandlungsroutine, die diesen Fehler ignoriert und den Programmablauf ungestört weiter machen lässt, sinnvoll meldet...

Also eventuell sowas:
Delphi-Quellcode:
type
  ERefreshError = Class(Exception);

...

procedure TfmTextverwaltung.myDataSetBeforeRefresh(DataSet: TDataSet);
begin
  try
    if meineAbbruchBedingung then begin
      raise ERefreshError.Create('Refresh nicht zulässig.');
    end;
  except
    on e: ERefreshError do begin
      // Das "Fressen" der Exception an dieser Stelle wirkt wie das Exit.
      // TDataSet.Refresh wird nicht ausgerufen.
      // ShowMessage(e.message);
    end;
  end;
end;

Sir Rufo 12. Dez 2015 16:36

AW: TDataSet.Refresh erweitern
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1324217)
Zitat:

Zitat von Der schöne Günther (Beitrag 1324204)
Ich habe keine Ahnung was du genau vorhast, aber vielleicht kannst du ja auch das
Delphi-Quellcode:
BeforeRefresh
-Event nutzen und dort einfach nur
Delphi-Quellcode:
Abort()
sagen :stupid:

(Abort wird sogar als Beispiel für TDataSet.BeforePost angeführt)

Danke für die Idee!
AFAIK springt Abort zum nächsten finally und beendet dann das Programm.
Wenn ich das BeforeRefresh überschreibe, dann kommt Refresh trotzdem in jedem Fall dran. Innerhalb von Refresh wird BeforeRefresh ausgeführt ...
danke trotzdem!

In der Doku kamm man nachlesen was Delphi-Referenz durchsuchenAbort denn so macht.

Ein genereller Programmabbruch erfolgt nicht.

ConnorMcLeod 12. Dez 2015 16:45

AW: TDataSet.Refresh erweitern
 
Leider kann/darf ich keinen Quellcode zeigen, das wäre auch etwas umständlich, aber das Prinzip geht so:

Delphi-Quellcode:
type
  // diese Klasse kann ich nicht verändern:
  TDataSetMitExtraFunktionalitaet = class(TDataSet)
  public
    procedure NichtAenderbar;
  end;

implementation

procedure TDataSetMitExtraFunktionalitaet.NichtAenderbar
begin
  // in dieser Prozedur kann ich nichts ändern
  [...]
  Refresh;
end;

procedure Demo;
var
  ds1: TDataSetMitExtraFunktionalitaet;
begin
  [...]
  // hier passiert ein implizierter Refresh, der unterdrückt werden soll:
  ds1.NichtAenderbar;
end;
Hoffe, das ist halbwegs verständlich ;-)

nahpets 12. Dez 2015 17:26

AW: TDataSet.Refresh erweitern
 
Prinzip ist verständlich, damit reicht der Quelltext (erstmal) aus:
Delphi-Quellcode:
type
  ERefreshError = Class(Exception);

type
  // diese Klasse kann ich nicht verändern:
  TDataSetMitExtraFunktionalitaet = class(TDataSet)
  public
    procedure NichtAenderbar;
  end;

implementation

procedure TDataSetMitExtraFunktionalitaet.NichtAenderbar
begin
  // in dieser Prozedur kann ich nichts ändern
  [...]
  Refresh;
end;

procedure EignesBeforeRefresh(DataSet: TDataSet);
begin
  if meineAbbruchBedingung then begin
    raise ERefreshError.Create('Refresh nicht zulässig.');
  end;
end;

// aber dashier ist änderbar?
procedure Demo;
var
  ds1: TDataSetMitExtraFunktionalitaet;
begin
  [...]
  // hier passiert ein implizierter Refresh, der unterdrückt werden soll:
  ds1.OnBeforeRefresh := EignesBeforeRefresh;
  Try
    ds1.NichtAenderbar;
  except
      // Das "Fressen" der Exception an dieser Stelle wirkt wie ein Exit in der RefreshMethode.
      // TDataSetMitExtraFunktionalitaet.Refresh wird nicht ausgerufen.
    on e: ERefreshError do;
  end;
  ds1.OnBeforeRefresh := Nil;
end;
Würde sowas helfen?

Natürlich scheitert das, wenn in der nichtänderbaren Routine sowas enthalten ist:
Delphi-Quellcode:
procedure TDataSetMitExtraFunktionalitaet.NichtAenderbar(DataSet: TDataSet);
begin
  [...]

  Refresh;

  [...] // Dashier würde dann nichtmehr ausgeführt.
         // Wenn das aber ausgeführt werden muss, dann kann man den Vorschlag vergessen.
end;
Ist denn der Quelltext von "NichtAenderbar" so, dass man eventuell auftretende Probleme erkennen kann und nach einer gezielten Lösung suchen kann?

ConnorMcLeod 12. Dez 2015 17:43

AW: TDataSet.Refresh erweitern
 
Yo, sehr nette Idee! Ich werde noch sicherheitshalber ein mglw bereits zugewiesenes OnBeforeRefresh Event in eine Variable retten und danach wieder auswechseln. Das wär's dann.
Vielen Dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:49 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz