Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Klasse mit Oberfläche verheiraten (https://www.delphipraxis.net/211088-klasse-mit-oberflaeche-verheiraten.html)

fisipjm 26. Jul 2022 15:24

Delphi-Version: 10.4 Sydney

Klasse mit Oberfläche verheiraten
 
Hi,

ich bin gerade dabei ein neues Objekt in ein bestehendes Projekt zu implementieren und bin über die Jahre doch ganz schön Faul geworden :-D

Ich würde gerne folgendes erreichen:

Ich habe eine Einfache klasse mit verschiedenen Infos Strings, Integer, Double Werte.
Also z.B.

Delphi-Quellcode:
type
  THouse = class
  private
    FHeight: double;
    FLength: double;
    FName: string;
    FID: integer;
    { private declarations }

  public
    property ID: integer read FID write FID;
    property Name: string read FName write FName;
    property Length: integer read FLength write FLength;
    property Height: integer read FHeigth write FHeight;
    { public declarations }
  end;
Dann noch eine Klasse die mir das als Array Kapselt mit Add und Delete Funktion. Den Krahm erzeugt und auch wieder frei gibt.

Delphi-Quellcode:
type
  THouses = class
  private
    { private declarations }

  public
    House : Array of THouse
    ...
    { public declarations }
  end;
Soweit eigentlich nix besodneres. Wenn ihr dass schon anders gemacht hättet, gern er damit. Ich kann hier immer super viel lernen :cyclops:

Was ich jetzt gerne hätte. Ich werde mir eine Grafische Komponente machen, die ich auf ein Panel platziere. Auf dieser Komponente werden dann Edits, bzw. Labels mit den entsprechenden Infos generiert, je nachdem wie viel Objekte in dem Array sind. Jetzt hätte ich es eigentlich gern, dass wenn ich in dem Array einen Wert ändere, die grafische Komponente direkt kapiert das sich da was getan hat und automatisch die Anzeige aktualisiert. Wie mach ich das am geschicktesten?

Grüße
PJM

himitsu 26. Jul 2022 15:39

AW: Klasse mit Oberfläche verheiraten
 
Normal kommt bei sowas in THouse/THouses eine Callback-Methode, wo sich die "Views" registrieren können.

quasi genauso, wie du bei einem TEdit etwas ans OnChange hängst und dann im Code auf Änderungen reagieren kannst.



Die vielen Edits:
Frames, bzw. das als View-Komponente wo die Edits drin sind ... also ein THouseView (wobei sich THouse und THouseView gegenseitig kennen, um Änderungen/Ereignisse auszutauschen) was mehrfach auf die Form/Panel drauf kommt.


Tipp: Hier im Forum suchenVisual LiveBindings / Bei Google suchenDelphi Visual LiveBindings

PS: Im FMX kann man in einer ListBox ein "Item" frei im FormDesigner gestalten, also mit allen Edits für je ein THouse.
Kann man sich in der VCL auch eine Listenkomponente basteln, welche dann mehrere THouse darstellen kann.

Uwe Raabe 26. Jul 2022 15:42

AW: Klasse mit Oberfläche verheiraten
 
Zitat:

Zitat von fisipjm (Beitrag 1509316)
Dann noch eine Klasse die mir das als Array Kapselt mit Add und Delete Funktion. Den Krahm erzeugt und auch wieder frei gibt.

Du meinst so was wie
Delphi-Quellcode:
TObjectList<THouse>
? TObjectList

fisipjm 26. Jul 2022 15:46

AW: Klasse mit Oberfläche verheiraten
 
Zitat:

Zitat von himitsu (Beitrag 1509319)
Normal kommt bei sowas in THouse/THouses eine
Tipp: Hier im Forum suchenVisual LiveBindings / Bei Google suchenDelphi Visual LiveBindings

PS: Im FMX kann man in einer ListBox ein "Item" frei im FormDesigner gestalten, also mit allen Edits für je ein THouse.
Kann man sich in der VCL auch eine Listenkomponente basteln, welche dann mehrere THouse darstellen kann.

Danke schon mal für die Hinweise, ich versuch mich mal rein zu wurschteln.
Was meinst du mit den LiveBindings? Ich hab ja blöderweise nur ein Klasse und keine Visuelle Komponente alla Memtable etc.. oder kann ich eine eigene Klasse auch über das LiveBinding ansprechen?:oops:

Bin leider an VCL gebunden, muss mir also was eigenes Basteln.

fisipjm 26. Jul 2022 15:51

AW: Klasse mit Oberfläche verheiraten
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1509320)
Zitat:

Zitat von fisipjm (Beitrag 1509316)
Dann noch eine Klasse die mir das als Array Kapselt mit Add und Delete Funktion. Den Krahm erzeugt und auch wieder frei gibt.

Du meinst so was wie
Delphi-Quellcode:
TObjectList<THouse>
? TObjectList

Im Prinzip ja. Hab halt wenig lust mich später um jedes Object einzeln kümmern zu müssen.
Mit den Aktuellen hab ich beim init Teil einmal ein Thouses.create und beim Destroy einmal ein Thouses.Free und benutz dazwischen nur noch Thouses.add, Thouses.delete(Thouse) usw. und brauch mich nicht mehr um die einzelnen Objects kümmern sondern nur noch um das Array.

Das liegt mir in 5 Jahren wahrscheinlich eher, wenn der Code mal wieder ins Refactoring muss.

himitsu 26. Jul 2022 15:57

AW: Klasse mit Oberfläche verheiraten
 
Zitat:

Zitat von fisipjm (Beitrag 1509324)
Bin leider an VCL gebunden, muss mir also was eigenes Basteln.

Vom Designer her darf man sich aber gern von sowas etwas abgucken, wenn man seine eigene Komponente und eventuell passende Design-Komponente (Komponenten-/Property-Editor) bastelt.

Zitat:

sondern nur noch um das Array
Die ObjectList kann sich dank Owned auch um die Verwalrung kümmern.

PS: für Listen im FormDesigner TCollection+TCollectionItem's statt TObjectList
z.B. die Params und FieldDefs in TDataSets, oder Actions im ActionManager, die Gesten im TGesture, Alles im TRibbon, Rows/Cols im TGrid uvm.

fisipjm 26. Jul 2022 16:06

AW: Klasse mit Oberfläche verheiraten
 
Zitat:

Zitat von himitsu (Beitrag 1509327)
Zitat:

Zitat von fisipjm (Beitrag 1509324)
Bin leider an VCL gebunden, muss mir also was eigenes Basteln.

Vom Designer her darf man sich aber gern von sowas etwas abgucken, wenn man seine eigene Komponente und eventuell passende Design-Komponente (Komponenten-/Property-Editor) bastelt.

Zitat:

sondern nur noch um das Array
Die ObjectList kann sich dank Owned auch um die Verwalrung kümmern.

Also im Prinzip anstatt einen einfach Klasse. Eine Ableitung von TObjectlist? Ich glaub ich habs noch nicht versatnden.:cry:

Edit:
Ich hab noch ein bisschen mehr in der Houses Klasse drin.
Z.B. eine Add Funktion mit der ich direkt die Inhalte über geben kann (Länge,Höhe,ID und Name) und dann einfach das Object zurück bekomme. Mit TObject müsste ich das Object immer erst erstellen und dann der ToBjectlist zuweisen, oder? Das wären dann deutlich mehr zeilen in meiner "main" Anwendung. So konnte ich es auf eine eigene Unit auslagern, oder steh ich grad komplett auf dem Schlauch?

KodeZwerg 26. Jul 2022 16:10

AW: Klasse mit Oberfläche verheiraten
 
Delphi-Quellcode:
type
  THouse = packed record
    FHeight: double;
    FLength: double;
    FName: string;
    FID: integer;
  emd;
  THouses = array of THouse;

 THouseClass = class
   strict private
     FHouses: THouses; // interne verwaltung
     FIndex: Integer; // interne verwaltung
     FCount: Integer; // interne verwaltung
   private
     procedure SetHouse(const AHouse: THouse); // schreibe das index element
     function GetHouse: THouse;                // hole das index element hervor
     procedure SetIndex(const AIndex: Integer); // versuche gewünschten index zu setzen
   public
     constructor Create;                                                                              // um FIndex und FCount zu initialisieren
     procedure Add(const AHeight, ALength: Double; const AName: string; const AID: Integer); overload; // haupt methode zum simplen adden
     procedure Add(const AHouse: THouse); overload;                                                   // neben methode die intern die haupt methode aufruft
     procedure Remove;                                                                                // löscht aktuellen index vom array
   public
     property Houses: THouses read FHouses write FHouses; // direkter zugriff aufs interne array (ich würde es entfernen)
     property House: THouse read GetHouse write SetHouse; // zugriff auf ein element basierend vom index
     property Index: Integer read FIndex write SetIndex;  // steuerung für einzel array zugriffe
     property Count: Integer read FCount;                 // sagt wieviel elemente wir haben
   end;

implementation

constructor THouseClass.Create;
begin
  FIndex := -1;
  FCount := 0;
end;

procedure THouseClass.SetHouse(const AHouse: THouse);
begin
  if ((FIndex > -1) and (FIndex < FCount)) then
    FHouses[FIndex] := AHouse;
end;

function THouseClass.GetHouse: THouse;
begin
  if ((FIndex > -1) and (FIndex < FCount)) then
    Result := FHouses[FIndex];
end;

procedure THouseClass.SetIndex(const AIndex: Integer);
begin
  if ((AIndex > -1) and (AIndex < FCount)) then
    FIndex := AIndex;
end;

procedure THouseClass.Add(const AHeight, ALength: Double; const AName: string; const AID: Integer);
var
  i: Integer;
begin
  i := Length(FHouses);
  SetLength(FHouses, i + 1);
  FHouses[i].FHeight := AHeight;
  FHouses[i].FLength := ALength;
  FHouses[i].FName  := AName;
  FHouses[i].FID    := AID;
  FIndex            := i;
  FCount            := Length(FHouses);
end;

procedure THouseClass.Add(const AHouse: THouse);
begin
  Self.Add(AHouse.FHeight, AHouse.FLength, AHouse.FName, AHouse.FID);
end;

procedure THouseClass.Remove;
begin
  if ((FIndex > -1) and (FIndex < FCount)) then
    begin
      Delete(FHouses, FIndex, 1);
      FCount := Length(FHouses);
      if FIndex >= FCount then
        FIndex := Pred(FIndex);
    end;
end;
Wäre es so nicht sinnvoller?

himitsu 26. Jul 2022 16:15

AW: Klasse mit Oberfläche verheiraten
 
Ob von TObjectlist abgeleitet oder darin ein Feld als TObjectList (statt deinem ArrayOf... eine TObjectList oder eine TCollection), ist erstmal egal. (kommt auf die Verwendung an)

Uwe Raabe 26. Jul 2022 16:43

AW: Klasse mit Oberfläche verheiraten
 
Zitat:

Zitat von fisipjm (Beitrag 1509328)
Also im Prinzip anstatt einen einfach Klasse. Eine Ableitung von TObjectlist? Ich glaub ich habs noch nicht versatnden.:cry:

Edit:
Ich hab noch ein bisschen mehr in der Houses Klasse drin.
Z.B. eine Add Funktion mit der ich direkt die Inhalte über geben kann (Länge,Höhe,ID und Name) und dann einfach das Object zurück bekomme. Mit TObject müsste ich das Object immer erst erstellen und dann der ToBjectlist zuweisen, oder? Das wären dann deutlich mehr zeilen in meiner "main" Anwendung. So konnte ich es auf eine eigene Unit auslagern, oder steh ich grad komplett auf dem Schlauch?

Entweder so:
Delphi-Quellcode:
type
  THouses = class(TObjectList<THouse>)
  procedure
    procedure Add(AID: Integer; const AName: string; AHeight, ALength: Double); overload;
  end;

procedure THoueses.Add(AID: Integer; const AName: string; AHeight, ALength: Double);
begin
  house := THouse.Create;
  house.ID := AId;
  house.Name := AName;
  house.Length := ALength;
  house.Width := AWidth;
end;

var
  Houses: THouses;
begin
  Houses.Add(1, 'Haus 1', 600.0, 400.0);
end;
oder so:
Delphi-Quellcode:
type
  THouse = class
  private
    FHeight: double;
    FLength: double;
    FName: string;
    FID: integer;
  public
    constructor Create(AID: integer; const AName: string; ALength, AHeight: double);
    property ID: integer read FID write FID;
    property Name: string read FName write FName;
    property Length: double read FLength write FLength;
    property Height: double read FHeight write FHeight;
  end;

constructor THouse.Create(AID: integer; const AName: string; ALength, AHeight: double);
begin
  inherited Create;
  FID := AID;
  FName := AName;
  FLength := ALength;
  FHeight := AHeight;
end;


type
  THouses = TObjectList<THouse>;

var
  Houses: THouses;
begin
  Houses.Add(THouse.Create(1, 'Haus 1', 600.0, 400.0));
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:33 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