Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Eigenschaften von erzeugten Komponenten (https://www.delphipraxis.net/162158-eigenschaften-von-erzeugten-komponenten.html)

Maya 10. Aug 2011 10:12

Eigenschaften von erzeugten Komponenten
 
Hallo ihr Lieben,

ich habe ein Formular erstellt, welches je nach vorheriger Auswahl sein Aussehen etwas ändert. Zu Deutsch: je nach Auswahl werden andere LabeledEdits erstellt bzw. an anderen Positionen sollen sie erscheinen.
Klappt soweit supi, macht auch das was ich will. XD

Nun zu meinen Problem.
Die LabeledEdits haben alle die gleichen Werte bei ihren Eigenschaften, bis auf Left, Top,Width und EditLabel.Caption. Mir ist aber leider nicht ganz klar, wie ich die einheitlichen Eigenschaften nur EINMAL deklarieren kann und die dann immer auf die Komponenten angewendet werden. Dabei geht es mir vor allem um die Schrift des Editlabels, welche dann anders ist, als ich sie möchte.
Hier mal ein Stückchen Quelltext.

Delphi-Quellcode:
var
    lbledtABS_VName:     TLabeledEdit;
   
[...]
implementation
[...]
procedure Tneuer_Eintrag.FormShow(Sender: TObject);
begin
[...]
    lbledtABS_VName:=TLabeledEdit.Create(grp1);
      with lbledtABS_VName do
        begin
          Parent:=grp1;
          Left:=16;
          Top:=42;
          EditLabel.Caption:='Vorname:*';
          Width:=121;
          Font.Name:='Arial';
          EditLabel.Font.Name:='Arial';
          Font.Size:=9;
          EditLabel.Font.Size:=9;
          Show;
        end;

end;
Wäre über einen Tipp froh, auch wenn irgendetwas doch noch unsauber sein sollte.

Liebe Grüße,
das Maya

DeddyH 10. Aug 2011 10:23

AW: Eigenschaften von erzeugten Komponenten
 
Ich bin zwar nicht sicher, ob ich Dich richtig verstanden habe, aber Du könntest doch eine Methode schreiben, die nur die veränderbaren Eigenschaften als Parameter übernimmt und die Komponenten dann erzeugt und konfiguriert.

himitsu 10. Aug 2011 10:29

AW: Eigenschaften von erzeugten Komponenten
 
Willst du jetzt sowas wie Defaultwerte haben, welche beim nächsten Erstellen genommen werden?

Entweder du machst das über eine externe Funktion/Ersteller-Klasse oder du fügst es direkt in die Komponenten ein.

- von TLabeledEdit ableiten
- als
Delphi-Quellcode:
class var
/
Delphi-Quellcode:
class property
die Defaultwerte hinzufügen
- den Constructor überschreiben und dort die (eventuell vorher gesetzten) Defaultwerte den entsprechenden Property zuweisen
- dann nur noch die fehlenden Werte zuweisen

Den Constructor kann man dann noch um die Parameter erweitern, für diejenigen Eigenschaften, welche sich immer ändern, wie z.B. die Position.

In deinem Fall würde ich grp1 als OwnerAndParent-Parameter gemeinsam dem Constructor übergeben und dazu noch Rect (TRect) oder Left, Top und Width, sowie die Caption.
Dazu dann noch Font-Name und Font-Size als Defaultwerte über Class-Property.

Maya 10. Aug 2011 10:35

AW: Eigenschaften von erzeugten Komponenten
 
Zitat:

Zitat von himitsu (Beitrag 1115911)
Willst du jetzt sowas wie Defaultwerte haben, welche beim nächsten Erstellen genommen werden?

Jupp. :)

Zitat:

Zitat von himitsu (Beitrag 1115911)
Entweder du machst das über eine externe Funktion/Ersteller-Klasse oder du fügst es direkt in die Komponenten ein.

- von TLabeledEdit ableiten
- als
Delphi-Quellcode:
class var
/
Delphi-Quellcode:
class property
die Defaultwerte hinzufügen
- den Constructor überschreiben und dort die (eventuell vorher gesetzten) Defaultwerte den entsprechenden Property zuweisen
- dann nur noch die fehlenden Werte zuweisen

Den Constructor kann man dann noch um die Parameter erweitern, für diejenigen Eigenschaften, welche sich immer ändern, wie z.B. die Position.

Ehrlich gesagt, das mit dem Ableiten hab ich bisher nie wirklich 100%ig hinbekommen. Gibt's ein gutes Tut, wo ich mir das noch mal anschauen kann?

Das mit einer externen Funktion, so in der Art hatte ich auch schon eine Idee, aber war mir nicht sicher, wie ich das effektiv hinbekomme. Dachte schon an eine Schleife, aber wirklich weitergekommen bin ich auf dem Weg auch nicht, da ich mir überlegte, dass über die Namen zu machen, aber die sind jedes Mal recht verschieden. Auch brauche ich halt nicht jedes Mal immer die gleichen LabeledEdits, mal brauche ich das für die Faxnummer, mal nicht.

himitsu 10. Aug 2011 10:43

AW: Eigenschaften von erzeugten Komponenten
 
So schwer ist das eigentlich nicht.
Delphi-Quellcode:
try
  TSimpleLabeledEdit = class(TLabeledEdit)
  private
    class var
      FDefaultFontName: String;
      FDefaultFontSize: Integer;
  public
    class property DefaultFontName: String read FDefaultFontName write FDefaultFontName;
    class property DefaultFontSize: Integer read FDefaultFontSize write FDefaultFontSize;

    constructor Create(AOwnerAndParent: TWinControl; ALeft, ATop, AWidth: Integer; ACaption: String; AVisible: Boolean = True);
  end;

constructor TSimpleLabeledEdit.Create(AOwnerAndParent: TWinControl; ALeft, ATop, AWidth: Integer; ACaption: String; AVisible: Boolean = True);
begin
  inherited Create(AOwnerAndParent); //den originalen Constructor aufrufen
  Parent:=AOwnerAndParent;
  Left:=ALeft;
  Top:=ATop;
  Width:=AWidth;
  EditLabel.Caption:=ACaption;
  Font.Name:=FDefaultFontName;
  EditLabel.Font.Name:=FDefaultFontName;
  Font.Size:=FDefaultFontSize;
  EditLabel.Font.Size:=FDefaultFontSize;
  Visible := AVisible; //Show bzw. Hide
end;
Und nun einfach TSimpleLabeledEdit verwenden.

Maya 10. Aug 2011 10:53

AW: Eigenschaften von erzeugten Komponenten
 
Zitat:

Zitat von himitsu (Beitrag 1115916)
So schwer ist das eigentlich nicht.

Sagst du. :)

Trotzdem hab ich zu dem Quelltext noch 'n paar Fragen.

Zitat:

Zitat von himitsu (Beitrag 1115916)
Delphi-Quellcode:
inherited Create(AOwnerAndParent); //Hier nix ändern, ja? Später bei der Anwendung der Komponente einfach dann grp1 und grp2 einsetzen.
  Parent:=AOwnerAndParent;
  Left:=ALeft;                          
  Top:=ATop;
  Width:=AWidth;
  EditLabel.Caption:=ACaption;  
  Font.Name:=FDefaultFontName;
  EditLabel.Font.Name:=FDefaultFontName;
  Font.Size:=FDefaultFontSize;           //Diese Eigenschaft soll sich ja nicht ändern. Ich bin mir jetzt nicht sicher, wo ich dann eingebe, dass die Schriftgröße 9 sein soll.
  EditLabel.Font.Size:=FDefaultFontSize;
  Visible := AVisible; //Show bzw. Hide
end;

Ich weiß, ich stell mich sicherlich gerade brodeldoof an. ;)

Dann noch eine Frage. Ich kann ganz normal dann Free verwenden, um die Komponenten wieder freizugeben, ja?
Wie gesagt, das Ableiten ist nicht meine Stärke.

DeddyH 10. Aug 2011 10:55

AW: Eigenschaften von erzeugten Komponenten
 
Nur blöd, wenn der übergebene Owner kein TWinControl ist :stupid:

[edit] Da der rote Kasten mal wieder versagt hat: das galt dem letzten Post von himitsu [/edit]

Maya 10. Aug 2011 10:58

AW: Eigenschaften von erzeugten Komponenten
 
@Deddy: Konnte ich mir schon denken. :D Bloß trotzdem verwirrst du mich jetzt noch ein Stückchen mehr.

DeddyH 10. Aug 2011 11:40

AW: Eigenschaften von erzeugten Komponenten
 
Ich würde das wie gesagt einfacher machen:
Delphi-Quellcode:
procedure TDeinForm.AddNewLabeledEdit(aLeft, aTop: integer; const aCaption: string);
var
  le: TLabeledEdit;
begin
  le := TLabeledEdit.Create(self);
  le.Left := Left;
  le.Top := aTop;
  le.EditLabel.Caption := aCaption;
  (* hier nun die gemeinsamen Eigenschaften definieren *)
  le.Parent := self; //oder ein Panel oder wo es sonst hinsoll
  (* usw. *)
end;
Um nun ein neues EditLabel anzulegen, rufst Du diese Methode auf und übergibst Left, Top und Caption in den Parametern.

Maya 10. Aug 2011 11:58

AW: Eigenschaften von erzeugten Komponenten
 
AH!! Deddy, jetzt ist der Groschen gefallen. Ging leider heute etwas centweise, für mich ist ja auch schon Freitag. ;)

Ich probier's gleich nach der Mittagspause aus.

himitsu 10. Aug 2011 12:28

AW: Eigenschaften von erzeugten Komponenten
 
Wobei das was in AddNewLabeledEdit oder im Constructor gemacht wird, im Grunde das Selbe ist ... nur eben an unterschiedlichen Stellen.

Maya 10. Aug 2011 13:22

AW: Eigenschaften von erzeugten Komponenten
 
Ich hab jetzt das ganze mal ausprobiert, aber leider noch zu keinen effektiven Ergebnis gekommen.
Den Quelltext habe ich ein klein wenig an meine Bedürfnisse angepasst.

Delphi-Quellcode:
procedure AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string);
[...]
implementation
[...]

procedure TneuerEintrag.AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string); //Zeile 86
var
  lbledt: TLabeledEdit;
begin
  lbledt:=TLabeledEdit.Create(self);
  lbledt.Left:=aLeft;
  lbledt.Top:=aTop;
  lbledt.Width:=aWidth;
  lbledt.EditLabel.Caption:=aCaption;
  lbledt.Name:='lbledt'+aName;
  lbledt.Parent:=aParent;

  lbledt.Font.Name:='Arial';
  lbledt.EditLabel.Font.Name:='Arial';
  lbledt.Font.Size:=9;
  lbledt.EditLabel.Font.Size:=9;
  lbledt.Show;
end;

[...]
Fehlermeldung: 'frmneuerEintrag' enthält kein Element namens 'AddNewLabeledEdit' in Zeile 86.
Für die Zeile kommt auch der Fehler, dass bei dem Punkt ein ; erwartet wurde und solche ähnlichen Späße.

Bin mir jetzt recht unsicher, wo mein Fehler liegt.

DeddyH 10. Aug 2011 13:23

AW: Eigenschaften von erzeugten Komponenten
 
Wo genau steht das
Zitat:

Delphi-Quellcode:
procedure AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string);

?

Maya 10. Aug 2011 13:27

AW: Eigenschaften von erzeugten Komponenten
 
Delphi-Quellcode:
type
  Tneuer_Eintrag = class(TForm)
    imgLogo: TImage;
    lblUberschrift: TLabel;
    lbl1: TLabel;
    lbledtPNr: TLabeledEdit;
    mmoBetreff: TMemo;
    lbl4: TLabel;
    dtp1: TDateTimePicker;
    lbl_Datum: TLabel;
    grp1: TGroupBox;
    btn3: TBitBtn;
    btn4: TBitBtn;
    grp2: TGroupBox;
    btn1: TBitBtn;
    btn2: TBitBtn;
    lbledtZuarbeit: TLabeledEdit;
    lbledtAblage: TLabeledEdit;
    dtpSchreiben: TDateTimePicker;
    lbl2: TLabel;
    dtpPost: TDateTimePicker;
    lbl3: TLabel;
    btnHinzu: TBitBtn;
    btnAbbrech: TBitBtn;
    procedure AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string);
    procedure FormShow(Sender: TObject);
    procedure btnAbbrechClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
So besser?

DeddyH 10. Aug 2011 13:31

AW: Eigenschaften von erzeugten Komponenten
 
OK, das ist schon die richtige Stelle. Auf den ersten Blick kann ich nichts Falsches entdecken, kannst Du die Unit mal anhängen?

Maya 10. Aug 2011 13:41

AW: Eigenschaften von erzeugten Komponenten
 
Na ja, viel spannendes gibt es da nicht zu sehen.

Delphi-Quellcode:
unit frmneuerEintrag;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, Buttons, ExtCtrls, jpeg;

type
  Tneuer_Eintrag = class(TForm)
    imgLogo: TImage;
    lblUberschrift: TLabel;
    lbl1: TLabel;
    lbledtPNr: TLabeledEdit;
    mmoBetreff: TMemo;
    lbl4: TLabel;
    dtp1: TDateTimePicker;
    lbl_Datum: TLabel;
    grp1: TGroupBox;
    btn3: TBitBtn;
    btn4: TBitBtn;
    grp2: TGroupBox;
    btn1: TBitBtn;
    btn2: TBitBtn;
    lbledtZuarbeit: TLabeledEdit;
    lbledtAblage: TLabeledEdit;
    dtpSchreiben: TDateTimePicker;
    lbl2: TLabel;
    dtpPost: TDateTimePicker;
    lbl3: TLabel;
    btnHinzu: TBitBtn;
    btnAbbrech: TBitBtn;
    procedure AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string);
    procedure FormShow(Sender: TObject);
    procedure btnAbbrechClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    Postart: Integer;
  end;

var
  neuer_Eintrag: Tneuer_Eintrag;


implementation

{$R *.dfm}

procedure TneuerEintrag.AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string);
var
  lbledt: TLabeledEdit;
begin
  lbledt:=TLabeledEdit.Create(self);
  lbledt.Left:=aLeft;
  lbledt.Top:=aTop;
  lbledt.Width:=aWidth;
  lbledt.EditLabel.Caption:=aCaption;
  lbledt.Name:='lbledt'+aName;
  lbledt.Parent:=aParent;

  lbledt.Font.Name:='Arial';
  lbledt.EditLabel.Font.Name:='Arial';
  lbledt.Font.Size:=9;
  lbledt.EditLabel.Font.Size:=9;
  lbledt.Show;
end;

procedure Tneuer_Eintrag.btnAbbrechClick(Sender: TObject);
begin
  Close;
end;


procedure Tneuer_Eintrag.FormShow(Sender: TObject);
begin
  if (Postart=1) then
    begin
      lbl_Datum.Caption:='Datum Posteingang:*';
      AddNewLabeledEdit(16,86,121,'Anrede:','ABS_Anrede',grp1);
    end;
end;
Danach kommt nix mehr. Ist ja noch alles im Aufbau.

DeddyH 10. Aug 2011 13:42

AW: Eigenschaften von erzeugten Komponenten
 
TneuerEintrag <> Tneuer_Eintrag ;) Ich hatte das erst für einen Tippfehler gehalten.

Gollum 10. Aug 2011 13:48

AW: Eigenschaften von erzeugten Komponenten
 
Hallo,

Zitat:

procedure AddNewLabeledEdit(aLeft, aTop, aWidth: Integer; const aCaption, aName, aParent: string);
der Parameter aParent sollte besser nicht von Typ String sein.

DeddyH 10. Aug 2011 13:49

AW: Eigenschaften von erzeugten Komponenten
 
Stimmt, TWinControl wäre passender (evtl. mit Defaultwert auf self) (geht nicht).

Maya 10. Aug 2011 13:53

AW: Eigenschaften von erzeugten Komponenten
 
*Head meets Desk*

Selber schon bemerkt und korrigiert.
Danke für eure Hilfe. ;)

So, hoffentlich letzte Frage: Wie bekomme ich die ganzen Komponenten am Ende am elegantesten freigegeben?
Wenn ich in das OnClose-Ereignis z.B. "lbledtABS_VName.Free" eingebe, kommt ja 'ne Fehlermeldung á la "undeklarierter Bezeichner", was ja klar ist. (Versuchen kann man es ja trotzdem mal. ;))

DeddyH 10. Aug 2011 14:44

AW: Eigenschaften von erzeugten Komponenten
 
Du hast ja beim Erzeugen einen Owner angegeben, daher musst Du die Komponenten nicht selbst freigeben, das übernimmt der Owner, das ist nämlich seine Aufgabe.

Maya 10. Aug 2011 14:47

AW: Eigenschaften von erzeugten Komponenten
 
Also müsste ich die Groupboxen freigeben?
Problem an der Sache ist aber, dass auch wenn ich die Form schließe und sie wieder öffne mit 'ner anderen Auswahl, motzt Delphi-Lein 'rum, weil einige Komponenten schon unter gewisse Namen vorhanden sind. D.h. sie sind nicht freigegeben wurden.

So und um mal meinen Gedankengang zu Ende zu führen: ich müsste die Groupboxen freigeben (sind zweie), wo die LabeledEdits drinne sind und beim neuen OnShow-Ereignis des Fensters neu erzeugen, ja?

DeddyH 10. Aug 2011 14:51

AW: Eigenschaften von erzeugten Komponenten
 
Der Owner ist das Formular, der Parent dürfte die jeweilige GroupBox sein. Während der Owner sich um den Speicher kümmert ist der Parent für die Darstellung zuständig. Aber das nur am Rande. Willst Du wirklich bei jedem OnShow-Eventaufruf die Komponenten neu erzeugen? Vielleicht wäre es dann einfacher, das Formular dynamisch anzulegen und freizugeben.

Maya 10. Aug 2011 14:58

AW: Eigenschaften von erzeugten Komponenten
 
Das Formular komplett dynamisch anlegen möchte ich eigentlich nicht, weil es immer komplett gleich aussieht, bis auf die knapp 15 LabeledEdits und max. 6 Comboboxen (je nach Auswahl), welche dynamisch erzeugt werden. Das sind ja auch nicht die einzigen Komponenten auf den Formularen.

Gibt es denn dann nicht eine Möglichkeit, das Formular richtig zu schließen und bei jeden Aufruf neu zu kreiieren, also nicht nur einfach anzuzeigen? Dann wären die Komponenten doch freigegeben und mein Problem eigentlich gelöst.

DeddyH 10. Aug 2011 15:01

AW: Eigenschaften von erzeugten Komponenten
 
Das meinte ich ja. Du kannst das Formular in den Projektoptionen aus der Liste der automatisch erstellten Formulare entfernen. Dann erzeugst Du es zur Laufzeit und stellst im OnClose die Action auf caFree. Das sollte eigentlich funktionieren, wenn ich nichts vergessen habe.

Maya 10. Aug 2011 15:10

AW: Eigenschaften von erzeugten Komponenten
 
Ok, das kannte ich noch gar nicht, jetzt hab ich aber ein ganz anderes Problem.
Wie ich ja schon erwähnte, wird vorher eine Auswahl getroffen und je nach dem wird dann das Formular erstellt. D.h. ich übergebe an die Unit frmneuerEintrag eine Variable (1,2 oder 3) und dementsprechend werden dann die Komponenten hingebastelt.

Somit sieht mein Quelltext in dem Auswahlformular wie folgt aus:

Delphi-Quellcode:
procedure TAuswahl.Hausmitteilung1Click(Sender: TObject);
begin
   Postart:=3;
   neuer_Eintrag.Postart:=Postart;
   neuer_Eintrag.ShowModal;
Jetzt kommt nämlich immer nach der Auswahl eine Fehlermeldung bzgl. einer Zugriffsverletzung. Ist ja auch klar, wenn das Formular noch gar nicht erzeugt ist, wie soll es da ja auch auf die Variable zugreifen?

DeddyH 10. Aug 2011 15:12

AW: Eigenschaften von erzeugten Komponenten
 
Delphi-Quellcode:
procedure TAuswahl.Hausmitteilung1Click(Sender: TObject);
begin
   Postart:=3;
   //Formular erzeugen
   neuer_Eintrag := Tneuer_Eintrag.Create(nil);
   neuer_Eintrag.Postart:=Postart;
   neuer_Eintrag.ShowModal;

Maya 10. Aug 2011 15:16

AW: Eigenschaften von erzeugten Komponenten
 
Ja, ich denke gerne mal viel zu komplizierten. Dachte, ich muss schon wieder tief in die Trickkiste greifen.

Ich wünsche mir einen Danke-Button hier her!

DeddyH 10. Aug 2011 15:21

AW: Eigenschaften von erzeugten Komponenten
 
Du gibst aber auch hoffentlich das Formular wieder frei (wie gesagt, z.B. über die CloseAction des Formulars im OnClose)?

Maya 10. Aug 2011 15:34

AW: Eigenschaften von erzeugten Komponenten
 
Also ich hab in dem Formular im OnClose-Ereignis dieses "Action:=caFree;" stehen, keine Sorge. Ich werde mich bloß noch mal etwa genauer mit der CloseAction beschäftigen, aber erst nach meinen langen WE. XD

DeddyH 10. Aug 2011 15:36

AW: Eigenschaften von erzeugten Komponenten
 
OK, dann sollte es auch keine Speicherprobleme geben.

himitsu 10. Aug 2011 15:43

AW: Eigenschaften von erzeugten Komponenten
 
Du kannst das caFree auch weglassen, aber dann mußt du entweder
Delphi-Quellcode:
neuer_Eintrag.Free;
, bzw.
Delphi-Quellcode:
FreeAndNil(neuer_Eintrag);
aufrufen,
wobei Free reicht und im Destructor des Tneuer_Eintrag ein
Delphi-Quellcode:
if neuer_Eintrag = Self then neuer_Eintrag := nil;
.
Obwohl man hier ebenfalls den Owner der Form nutzen könnte, um diese über diesen Owner freigeben zu lassen. (oder eine Kombination aus Allem)

Wobei man die globale Variable
Delphi-Quellcode:
neuer_Eintrag
auch ganz entfernen könnte und nur eine lokle Variable (für das Erstellen) ausreicht, wenn man sonst keinen externen Zugriff benötigt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:24 Uhr.

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