AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Form + DataModule mehrere Instanzen

Ein Thema von Nersgatt · begonnen am 31. Jul 2017 · letzter Beitrag vom 31. Jul 2017
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 10:57
Moin,

ich habe zu fast jedem Formular auch ein entsprechendes Datenmodul, wo das nichtvisuelle Zeugs liegt. Also Queries, Datasets, DataSources und sowas. Auch mal ne Imagelist, usw.

Nun möchte ich gern von einigen Formularen mehrere Instanzen öffnen und dazu soll auch jede Instanz des Formulars eine eigene Instanz des Datenmoduls bekommen. Wie stelle ich da die Verbindung zwischen der Instanz des Datenmoduls und der Instanz der Formulars her?

Danke!
Jens
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#2

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 11:55
Mach' Dir 'nen Nachfahren von TForm (oder Deiner aktuell genutzten Formularvariante), gönne dem Nachfahren ein Attribut DataModule vom Typ TDataModule.

Dann kannst Du im Objektinspektor dem Formular ein DataModule zuweisen, analog z. B. zu der Eigenschaft DataSet bei 'ner DataSource.

Grob in Delphi:
Delphi-Quellcode:
Type
  TfmMeinDataModulForm = class(TForm)
    fDataModule : TDataModule;
    ...
  public
    property DataModule : TDataModule read GetDataSource write SetDataSource;
    ...
  end;

implementation

...

function TfmMeinDataModulForm.GetDataModule : TDataModule;
begin
  Result := fDataModule;
end;

procedure TfmMeinDataModulForm.SetDataSource(ADataModule : TDataModule);
begin
  fDataModule := ADataModule;
  if Assigned(fDataModule) then begin
    ... // eventuell erforderliche weitere Zuweisungen, Plausibilitätsprüfungen ...,
        // in Bezug auf das DataModule.
        // Z. B.: Sind dort die erforderlichen DataSets ... vorhanden ...
  end;
end;
Im Programmquelltext wäre dann ein Zugriff auf das DataModule in der Form
Delphi-Quellcode:
  ...
  Self.DataModule.JedePublicEigenschaftDesDataModules.UndDerenEigenschaftenUndOderMethoden(ggflsMitParametern);
  ...
  Self.DataModule.DataSource1.DataSet.Open;
  while not Self.DataModule.DataSource1.DataSet.EoF do begin
    // ... irgendwas mit den Daten machen ...
    Self.DataModule.DataSource1.DataSet.Next;
  end;
möglich.

Wenn's ohne extra Nachfahren sein soll, kannst Du auch unter private eine Eigenschaft FDataModule vom Typ TDataModule anlegen und im FormCreate (oder sonstiger passender Stelle) ein DataModule erstellen und zuweisen. Der Zugriff geht wie oben.

Das ist jetzt nur grob als Idee beschrieben, es gibt bestimmt auch noch andere Lösungen.

Geändert von nahpets (31. Jul 2017 um 11:59 Uhr) Grund: Text ergänzt.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.119 Beiträge
 
Delphi 12 Athens
 
#3

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:09
Zitat:
Dann kannst Du im Objektinspektor dem Formular ein DataModule zuweisen, analog z. B. zu der Eigenschaft DataSet bei 'ner DataSource.
Aber nur wenn der OI dieses Property auch anzeigt.

Public wird sowieso niemals im OI angezeigt. (nur Published)

Und Published-Properties, welche man direkt in der aktuell bearbeiteten Formklasse deklariert hat, sind eh nicht sichtbar.
Maximal immer nur die Property des Vorfahren, aber hier fällt die IDE fast immer auf TForm als Vorfahre zurück, auch wenn man dazwischen noch weitere Ableitungen hat.

Vermutlich muß man den Vorfahren mit diesem Property als "Vorlage" bei Delphi registrieren, damit man das Property im OI sieht.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (31. Jul 2017 um 12:12 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#4

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:25
Selbst wenn man die Eigenschaften nicht im Objektinspektor zu sehen bekommt, die "händische" Variante funktioniert auf jeden Fall.

Und da ja von einem Formular mehrere Exemplare erstellt werden sollen, müssen entsprechend gleichviele Datenmodule erstellt werden. Eine Zuweisung im Objektinspektor wäre hier (vermutlich) eh nicht hilfreich, da dort ja alle Formulare auf das gleiche Datenmodul verweisen würden.

Also würde (vermutlich) eine Eigenschaft FDataModule unter private mit 'ner Zuweisung das Datenmoduls nach seiner Erstellung in FormCreate (oder ähnlich) ausreichen.

Oder ginge (sinngemäß) auch sowas?
Delphi-Quellcode:
Type
  TForm1 = class(TForm)
    ...
  private
    fDataModule : TDataModule;
    ...
  end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin
  fDataModule := TMeinDatenModul.Create(Self);
end;
Dann kann über fDataModule auf das Datenmodul zugegriffen werden.
  Mit Zitat antworten Zitat
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#5

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:31
Ich glaube, mein Problem ist nicht richtig verstanden worden.

Ich hab ein Formular (TfrmFoo) und ein DatenModul (TdmFoo).

Im Formular liegt z.B. ein Grid. Als Datenquelle für das Grid gebe ich im Objektinspektor dmFoo.dsDaten an.
Wenn ich nun eine Instanz von frmFoo erzeuge, erzeuge ich in der Regel im FormCreate die dazugehörige Instanz von dmFoo. So funktioniert das gut.
dmFoo := TdmFoo.Create(Self) (dmFoo ist die globale Variable, die Delphi bei jedem Datenmodul im Quelltext des Datenmoduls erzeugt)

Das funktioniert so lange gut, solange ich von frmFoo nur einen Instanz erzeuge.
Erzeuge ich eine weitere Instanz von frmFoo, wird dmFoo erneut erzeugt. Damit hab ich 2 Probleme:
1. Ein Speicherleck (das ist aber hier nicht mein Problem)
2. in beide Instanzen von TfrmFoo benutzen die zuletzt erzeugte Instanz von TdmFoo. Das ist mein eigentliches Problem.

Ich möchte, dass die erste Instanz von frmFoo auf eine Instanz von dmFoo hat. Sonst zeigen die Grids ja in beiden Formularen das selbe an.
Jens
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.119 Beiträge
 
Delphi 12 Athens
 
#6

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:35
Nee, dein Problem ist hierbei eher, dass du bei dmFoo := TdmFoo.Create(Self) die globale Variable verwendest, anstatt einer lokalen Variable (ein Feld in TfrmFoo).

Tipp: Am Einfachsten immer als Erstes diese globale Variable löschen (außer "eine" Instanz davon lässt du automatisch von Delphi erzeugen > siehe DPR/Projektoptionen)
Und schon kommt man garnicht erst auf die Idee diese Variable ausversehn nutzen zu wollen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (31. Jul 2017 um 12:37 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#7

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:38
Deshalb ja keine globale Variabel dmFoo, sondern die private Eigenschaft fDataModule.

Im FormCreate dann statt dmFoo := TdmFoo.Create(Self) halt fDataModule := TdmFoo.Create(Self) und im übrigen Quelltext alle Zugriffe auf dmFoo durch fDataModule ersetzen.
  Mit Zitat antworten Zitat
Benutzerbild von Nersgatt
Nersgatt

Registriert seit: 12. Sep 2008
Ort: Emlichheim
693 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:39
Nee, dein Problem ist hierbei eher, dass du bei dmFoo := TdmFoo.Create(Self) die globale Variable verwendest, anstatt einer lokalen Variable (ein Feld in TfrmFoo).
Eine lokale Variable würde sehr gern verwenden, wenn ich wüsste, wie ich dann im Objektinspektor angeben kann, dass die Datenquelle FdmFoo.dsDaten ist und nicht dmFoo.dsDaten.
Natürlich könnte ich im Quellcode die Properties setzen. Aber dann verliere ich ja alle Vorteile, die das "R" im Wort "RAD" repräsentiert.
Jens
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.733 Beiträge
 
Delphi 6 Enterprise
 
#9

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:50
In dem Fall wäre es vllt. nötig, auf das Datenmodul zu verzichten und den ganzen Nichtvisuellen Teil auch auf die Form zu packen. Vielleicht nicht schön/übersichtlich, aber es funzt. Dies ist mMn ein Problem der Kategorie: "Irgendeinen Tod musst du sterben".
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.119 Beiträge
 
Delphi 12 Athens
 
#10

AW: Form + DataModule mehrere Instanzen

  Alt 31. Jul 2017, 12:52
Das leider garnicht.
Praktisch kannst du im Formdesigner immer nur mit einer globalen Instanz (Signleton) deines DatenModuls arbeiten.

Du kannst aber im Create, vor dem Inherited eine Instanz deines Datenmoduls erzeugen. (es darf aber zur Laufzeit keine automatisch erzeugte Instanz dieses Moduls existieren, bzw. diese wird vorher umbenannt oder freigegeben)
DatenModule registrieren sich global im Delphi und der Form-Loader findet sie dann über ihren Namen, bzw. mann kann sich selber ein GetGlobalDataModule-Event registrieren.

Nach dem Laden (nach dem Create-Inherited oder spätestens im TForm.Loaded) dann das Datenmodul umbenennen (oder den Namen löschen > '' ), damit es mit späteren Instanzen deiner Form keine Überschneidungen gibt.

In der IDE muß aber eine "globale" Instanz vorhanden sein.
Gegen diese kannst du dann Designen (in der DFM wird der Name gespeichert) und beim Laden deiner Form im laufenden Programm wird dann jeweils die aktuelle/individuelle Instanz mit diesem Namen verwendet.

Statt vorher eine neue Datenmodul-Instanz zu erzeugen erstmal die globale Instanz verwenden und dann nach dem Laden der Form die "Globale" umbenennen, eine neue Instanz mit dem alten Namen erzeugen und der globalen Variable zuweisen (für ein eventuell nachfolgendes Laden weiterer Formen)




Tipp:
Wir haben bei uns ein paar DatenModule, die aber in verschiedenen Packages liegen und von der IDE leider nicht immer gefunden werden, wenn man nicht zufällig die Unit dieses DatenModules geöffnet hat, wenn gerade ein anderes Package aktiv ist.
Delphi scheint da nicht immer alle Packages "geladen" zu haben und dann existiert keine Instanz dieses Datenmoduls, was dann beim Öffnen der Form im FormEditor gern mal knallt.

Es gibt zwar in den geladenen DesignPackages nochmal eine Instanz, aber diese wird nicht vom FormDesigner gefunden, bzw. diese manuell erstellten Module werden nicht gefunden-
Aus diesem Grund hab ich unsere Instanzen der DesignTime-Packages auch nochmal manuell in der IDE "registriert".
Delphi-Quellcode:
RegisterFindGlobalComponentProc(FindGlobalModules); // im Class-Constructor des TIDEHelperModul
UnregisterFindGlobalComponentProc(FindGlobalModules);

class function TIDEHelperModul.FindGlobalModules(const Name: string): TComponent;
begin
  Result := nil;
  if SameText(Name, 'DM1') then Result := UDM1.DM1;
  if SameText(Name, 'DMSys') then Result := USysModule.DMSys;
end;



Alternativ eben nochmal der Vorschlag von nahpets.
Zitat:
Delphi-Quellcode:
procedure TfmMeinDataModulForm.SetDataSource(ADataModule : TDataModule);
begin
  fDataModule := ADataModule;
  if Assigned(fDataModule) then begin
    ... // eventuell erforderliche weitere Zuweisungen, Plausibilitätsprüfungen ...,
        // in Bezug auf das DataModule.
        // Z. B.: Sind dort die erforderlichen DataSets ... vorhanden ...
  end;
end;
Siehe die Kommentare.
Im OI nichts zuweisen, sondern das im Setter der Form an die Unterkomponenten durchreichen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (31. Jul 2017 um 13:07 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:21 Uhr.
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