![]() |
Delphi-Version: 10 Seattle
Spezieller TFrame
Guten Morgen,
ich steh grad irgendwie auf dem Schlauch: Gibt es eine Moeglichkeit, einen TFrame zu definieren, bei dessen Kindern klar ist, dass sie immer ein
Code:
haben?
Icon: TImage;
Im constructor einer Klasse, wo ich normalerweise einen TFrame erstelle, moechte ich einfach TMeinSpeziellerFrame neben der Angabe eines AIcon: TImage erstellen, so dass dem Frame das Icon direkt mitgegeben wird:
Code:
Das Urproblem ist also, dass ich den TFrame im Formdesigner in der .dfm nicht von TMyFrameClass ableiten kann.
TMyFrameClass = class(TFrame)
Icon: TImage; end; TMyClass = class public FMyFrameList: TObjectDictionary<String, TMyFrameClass>; constructor Create(AOwner: TComponent; AIcon: TImage); end; implementation constructor TMyClass.Create(AOwner: TComponent; AIcon: TImage); begin FMyFrameList := TObjectDictionary<String, TMyFrameClass>.Create; FMyFrameList.Add('ExampleFrame', TMyFrameClass.Create); FMyFrameList['ExampleFrame'].Icon := AIcon; end; Der muss erzwungenermassen von TFrame abgeleitet werden (nicht von dessen Nachfahren), sonst spackt die IDE und ich kann den Frame im designer nicht mehr oeffnen. Wie wuerdet Ihr diese Sachlage loesen? |
AW: Spezieller TFrame
Du tust dir keinen Gefallen damit das mit aller Gewalt in den Konstruktor drücken zu wollen. Die IDE weiß von deinem Spezial-Konstrukt nicht, sie arbeitet mit dem Constructor
Delphi-Quellcode:
der schon von
Create(AOwner: TComponent)
Delphi-Quellcode:
(oder
TComponent
Delphi-Quellcode:
?) vererbt wird.
TControl
Klar kannst du das machen, und deine Frames so über eigenen Code erstellen, einbauen und alles. Aber der Formular-Designer der IDE wird immer den Konstruktor
Delphi-Quellcode:
aufrufen.
Create(AOwner: TComponent)
Mach dir eine Basisklasse
Delphi-Quellcode:
der schonmal das
TMyBaseFrame
Delphi-Quellcode:
enthält. Du entdeckst später sicher noch mehr Gemeinsamkeiten die sich alle in eine Oberklasse auslagern lassen.
TImage
Wenn du jetzt einen speziellen Frame bauen willst leitest du den noch von
Delphi-Quellcode:
ab, sondern von
TFrame
Delphi-Quellcode:
(Datei -> Neu -> Weitere -> Vererbbare Elemente -> TMyBaseFrame).
TMyBaseFrame
|
AW: Spezieller TFrame
Zitat:
Many thanks! |
AW: Spezieller TFrame
Das war übrigens der umständliche Weg, schneller findest du deine Basisklassen-Frames (und Forms und Datenmodule) wenn du in die Toolpalette (Strg+Alt+P) schaust wenn der Formular-Designer nicht geöffnet ist. Dann einfach einen Eintrag daraus auswählen und schon hast du eine neue Ableitung von
Delphi-Quellcode:
erstellt.
TMyBaseFrame
|
AW: Spezieller TFrame
Zitat:
Es geht ja darum, diese frames programmatisch zu erstellen und einfach ein Icon mitzugeben :( Was mich wieder zu meiner Urspruenglichen Frage bringt: Wie kann ich einen Type(TFrame) definieren, bei dem klar ist, dass er unbedingt ein Icon: TImage enthaelt, so dass ich dieses irgendwie programmatisch zuweisen kann? |
AW: Spezieller TFrame
Zitat:
Der Frame selber kann ruhig den std-ctor haben |
AW: Spezieller TFrame
Zitat:
Wenn Du allerdings einen festen Satz von Icons hast gibt es noch eine andere Möglichkeit. Da könntest Du der Basisklasse eine TImagelist mit dem vollen Satz der Icons verpassen, einen enumerated Type mit entsprechend vielen Elementen definieren, dem Frame eine published property dieses Typs mit einer Settermethode verpassen, und diese dann das gewünschte Icon aus der Imagelist in das Icon-TImage kopieren lassen. |
AW: Spezieller TFrame
Zitat:
Die Idee ist, einen TMyBaseFrame in der IDE zu erstellen, der eine Member/Feldvariable Icon: TImage hat. Von dem will ich Frames ableiten (programmatisch erstellen), die leicht anders aufgebaut sind, aber auch immer ein Icon: TImage haben. Ueber die Klasse TMyBaseFrame sollte somit im code klar sein, dass sie immer dieses TMyBaseFrame.Icon: TImage; beinhaelt. Denn dann kann ich einfach generell bei so einem Frame auf
Code:
zugreifen.
TMyCoolFrame = class(TMyBaseFrame)
... AMyCoolFrame := TMyCoolFrame.Create(AOwner); AMyCoolFrame.Icon := TImage(Whatever); Wenn ich also wie man es normal vermuten wuerde, einfach eine neue Klasse von TFrame ableite und ein Member Icon hinzufuege, war nicht moeglich, in der IDE im Code TMyCoolFrame = class(TFrame) abzuaendern in TMyCoolFrame = class(TMyBaseFrame), so dass bekannt ist, dass ein Icon enthalten ist und gleichzeitig trotzdem das Editieren des TFrame im FormEditor moeglich ist (F12). Kurz gesagt wie in Post 1 geschrieben. "war nicht moeglich", weil ich es mittlerweile geschafft habe. Was fuer ein Teufelsritt, ich weiss gar nicht, warum die IDE sich da so scheut :wall: |
AW: Spezieller TFrame
Als Gedankenanstoß:
Du könntest auch ein Interface dazunehmen, und so dein TFrame zwingen entsprechende Felder und Routinen anzulegen.
Delphi-Quellcode:
Das funktioniert dann auch im Designer wie gewohnt,
TMyCoolFrame = class(TFrame, IMyCoolFrame)
aber ich denke du möchtest von der Basisklasse ableiten eben um dir das Anlegen in jedem Frame zu sparen. |
AW: Spezieller TFrame
Nur wenn man auf Zugriffsverletzungen und ähnliches steht.
Nie Interface- und TObject-basierte Referenzierung mischen :warn: |
AW: Spezieller TFrame
Was geht ist folgendes:
Wir erstellen uns manuell eine Ableitung von
Delphi-Quellcode:
:
TFrame
Delphi-Quellcode:
Dann erstellen wir uns ein neues
unit CustomFrameApp.Frames.MyBaseFrame;
interface uses Vcl.ExtCtrls, Vcl.Forms; type TMyBaseFrame = class(TFrame) private FIcon: TImage; published property Icon: TImage read FIcon write FIcon; end; implementation end.
Delphi-Quellcode:
wie gehabt und verändern den Source leicht:
TFrame
Delphi-Quellcode:
unit CustomFrameApp.Frames.MyFrame;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, // die Unit mit dem Vorgänger-Frame CustomFrameApp.Frames.MyBaseFrame; // Umbiegen der Klasse TFrame auf die gewünschte Klasse type TFrame = CustomFrameApp.Frames.MyBaseFrame.TMyBaseFrame; type TMyFrame = class(TFrame) private { Private-Deklarationen } public { Public-Deklarationen } end; implementation {$R *.dfm} end. |
AW: Spezieller TFrame
Zitat:
Das Problem, auf welches du dich beziehst ist dort, wo die Referenzzählung die Instanz aus dem Speicher kicken kann, da sollte man nur noch per Interface auf die Instanz zugreifen. |
AW: Spezieller TFrame
Zitat:
Muss ich mal testen. Mein Loesungsweg war dann doch ne Ecke umstaendlicher... |
AW: Spezieller TFrame
Zitat:
|
AW: Spezieller TFrame
Das Problem ist, dass die IDE nach dem Namen der Vorgänger-Klasse schaut, wenn der Vorgänger keine DFM Datei hat.
Wenn dann der Name der Vorgänger-Klasse <>
Delphi-Quellcode:
dann wird das Dingen wie ein
TFrame
Delphi-Quellcode:
behandelt. Das ist das ganze Geheimnis.
TForm
Auf das gleiche Problem trifft man übrigens auch bei
Delphi-Quellcode:
(aber wahrscheinlich seltener, weil man da nicht so viel ableitet).
TDataModule
|
AW: Spezieller TFrame
Zitat:
|
AW: Spezieller TFrame
Zitat:
Es war notwendig, die TFrame-Abgeleitete Basisklasse, die man TMyCoolFrame zur Ableitung reicht, vollstaendig leer zu erstellen, dann als Basisklasse anzugeben. Wenn dieses Konstrukt zusammen mit dem "inherited" in der .dfm statt "object" mal steht, kann man in der Basisklasse aendern, was man will. |
AW: Spezieller TFrame
Zitat:
|
AW: Spezieller TFrame
Zitat:
Der Zugriff ist dann natürlich ausschliesslich über Interfaces. |
AW: Spezieller TFrame
Zitat:
ja, das ist eine super Lösung. Ich benutze das "Umbiegen" in ähnlicher Form an einigen Stellen. Ich frage mich wie das "Umbiegen" als Fachbegriff heisst, weil ich nenne das für mich manchmal Unit-Forwarding. Hat diese Methode vielleicht einen klaren Namen ? |
AW: Spezieller TFrame
Zitat:
|
AW: Spezieller TFrame
Aha, dankesehr.
Man lernt nie aus. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:56 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-2025 by Thomas Breitkreuz