Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Objekteigenschaft übergeben? (https://www.delphipraxis.net/144127-objekteigenschaft-uebergeben.html)

moelski 30. Nov 2009 20:18


Objekteigenschaft übergeben?
 
Moin !

Gibt es eigentlich die Möglichkeit eine Objekteigenschaft direkt zu übergeben?

Wenn ich z.B. eine Procedure aufrufe mit HalloWelt(Edit1.text) dann kommt in der procedure nur der Text an den das Edit1 bereitstellt bzw. wird das wohl ein Zeiger sein :gruebel:
Anyway ... Besteht auch die Möglichkeit die Objekteigenschaft zu übertragen so das ich in der Procedure auch die zugehörige Klasse (TEdit) ermitteln kann und auch den Typ der Eigenschaft (in dem Fall String)? Und natürlich auch darüber den Wert auslesen ...
Wobei im Prinzip der Eigenschaftstyp und der Wert reichen würden.

Hoffe (mal wieder) ich habs einigermassen verständlich umschrieben :stupid:

Andreas L. 30. Nov 2009 20:22

Re: Objekteigenschaft übergeben?
 
Du kannst deiner procedure einen Parameter vom Typ TComponent verpassen:

Delphi-Quellcode:
procdure HalloWelt(AComponent: TComponent);
begin
  if AComponent is TEdit then
    TEdit(AComponent).Text := 'Hallo, Welt!'
  else
    ShowMessage('Kein TEdit übergeben sondern folgende Klasse: ' + AComponent.ClassName);
end;

....
....


HalloWelt(Edit1);
HalloWelt(Button1);
etc...

moelski 30. Nov 2009 20:36

Re: Objekteigenschaft übergeben?
 
Moin !

Zitat:

Du kannst deiner procedure einen Parameter vom Typ TComponent verpassen
Ok das würde auch funktionieren. Aber damit habe ich noch nicht den richtigen Eigenschaftswert. Den könnte man evtl. als String mitgeben und dann über RTTI (TypInfo) auslesen ob a) der Wert existiert, b) welcher Typ es ist und c) den Wert auslesen.

Hmm erscheint mir etwas kompliziert. Geht das nicht noch einfacher ?

Medium 30. Nov 2009 20:42

Re: Objekteigenschaft übergeben?
 
Wie erkennst du einen "richtigen" Eigenschaftswert?

moelski 30. Nov 2009 20:49

Re: Objekteigenschaft übergeben?
 
Moin !

Zitat:

Wie erkennst du einen "richtigen" Eigenschaftswert?
Gute Frage. Über RTTI und eine Typbestimmung?

Aber da ich noch nichtmal weiss ob das mit den Eigenschaften so überhaupt irgendwie klappen könnte kann ich das nicht wirklich beantworten.

himitsu 30. Nov 2009 20:50

Re: Objekteigenschaft übergeben?
 
Was du willst, das geht nicht

und der Trick mit den RTTI geht auch standardmäßig nur mit published Properties.

Zitat:

Gute Frage. Über RTTI und eine Typbestimmung?
die RTTI gibt den Pointer zur Setter- und Getter-Prozedur raus, soweit vorhanden,
den Namen des Property und dessen Typ.

moelski 30. Nov 2009 20:55

Re: Objekteigenschaft übergeben?
 
Moin himitsu,

ich habs ja schon fast befürchtet :-D

Anyway danke für die Aufklärung :thumb:

Zitat:

und der Trick mit den RTTI geht auch standardmäßig nur mit published Properties.
Ok das wäre gegeben. Naja mal sehen wie ich das nun löse.

Prinzipiell geht es um das "Problem" aus diesem Thread:
http://www.delphipraxis.net/internal...t.php?t=169459

Medium 30. Nov 2009 20:55

Re: Objekteigenschaft übergeben?
 
Meine Frage zielte eher darauf ab, was du als die richtige ansiehst. Klar, über die RTTI kannst du einen übergebenen String mit den Namen der published Properties vergleichen, und selbst den Typ kann man glaube ich als String da raus holen. Für mich klang es erst so, als wolltest du irgend einen Automatismus haben, der eine (wozu auch immer) passende Eigenschaft automatisch ermittelt, deren Name bei Übergabe u.U. unbekannt ist.


Edit: Dein Vorhaben sieht diesem hier ziemlich ähnlich scheint mir.

moelski 30. Nov 2009 21:06

Re: Objekteigenschaft übergeben?
 
Moin Medium,

was ich ja im Grunde erreichen möchte ist folgendes:
ich möchte vom User erstallbare Verknüpfungen zwischen 2 Objekteigenschaften erreichen.

Bsp: wie auch im anderen Fred:
2 Edits. Das was in Edit 1 eingetragen wurde soll nach Enter in Edit 2 erscheinen.

In Code wäre das ein einfacher Aufruf von "Edit1.text := Edit2.text".
Aber das möchte ich eben für den User editierbar haben. Er soll also aus einer Art "Eingangsliste" Eigenschaften auswählen können die er dann anderen Objekten (bzw. deren Eigenschaften) zuordnen kann.
Und das sollte eben recht universell funktionieren also z.B. auch mit Integer werten.

Medium 30. Nov 2009 21:18

Re: Objekteigenschaft übergeben?
 
Das würde ich mit einer nicht-visuellen Komponente lösen, die einen kleinen eigenen Property-Editor mit bringt. Ich hatte da die Tage so ein Ding in der Hand, dass alle auf dem Formular liegende Kompos hat auflisten können, sowie ihre published Properties. Das war Teil einer OPC-Komponentensammlung, wo Eigenschaften direkt angebunden wurden, so dass man selbst kein Polling betreiben muss um die Werte zu aktualisieren. Bei dir wäre die Quelle dann nicht ein OPC Unterbau, sondern eine andere Komponente.

Dieser Editor + Auflistung der Kompos und Eigenschaften ist aber nur die halbe Miete. In dem verlinkten Thread ging es schon darum, wie man nun generisch die Änderung einer beliebigen Eigenschaft einer prinzipiell unbekannten Komponente erkennen kann, und DA liegt dann auch der Hund begraben.

moelski 30. Nov 2009 21:33

Re: Objekteigenschaft übergeben?
 
Moin !

Naja unbekannt sind sie nicht ganz.
Die Komponenten die verwendet werden sollen sind schon bekannt. Das ist vornehmlich TChart bzw. TSeries.

Die Komponente wo der Wert (es ist meist ein Double Wert) eingetragen werden soll ist entweder ein Gauge (Abakus VCL) oder als String in ein Edit / Label.

Es muss also nicht 100% generisch sein.

Zitat:

die einen kleinen eigenen Property-Editor mit bringt
Ja das klingt gut. Hast du da etwas brauchbares im Kopf was man da verwenden könnte?

Medium 30. Nov 2009 22:13

Re: Objekteigenschaft übergeben?
 
Ich hab befürchtet dass du sowas fragst :mrgreen:. Ich hab selber noch nie einen Prop-Editor gebaut (bzw. bauen müssen), und die genannte Kompo ist leider Closed-Source. Irgendwo hier schwirrt meine ich aber auch ein Tutorial zu Editoren rum. Das Auflisten der Komponenten ließe sich ja recht simpel via Parent.Controls[] machen, und deren Properties dann über die RTTI.

Da du anders als Neutral General im anderen Thread wohl nicht auf einen gänzlich generischen Einsatz auch von anderen setzt, würde es Sinn machen von den wertgebenden Komponenten eine eigene Ableitung zu benutzen. Diese reicht im Grunde nur alles weiter an ihren Vorfahren, implementiert aber zusätzlich eine Binding-Property (für die dann besagter Editor wäre). Zudem verdeckt sie die zu überwachende Property des Vorfahren, und bekommt dafür einen Setter der neben dem Setzen der Property auch das Aktualisieren der gebundenen Komponente auslöst. Ansonsten müsstest du entweder sehr unschön in der VMT der Wertgeber fummeln um den Setter zu "hooken" (was nichtmal immer möglich ist, nämlich wenn eine Property nicht über eine Setter-Methode sondern gleich in ein Feld geht), oder aber mit einem Timer pollen, was fast noch unschöner ist :)

Bei den Charts bzw. Series kann es aber dennoch ungemütlich werden... Ich bin mir grad unsicher, ob ein Chart seine Series als published Property hält. Wenn nicht, gibt es keinerlei RTTI-Infos über sie. Dann müsstest du explizite Angaben beim Binding machen, da nix aufgelistet werden kann. Gemein ist dabei auch, dass die Series keine elementare Property sind, und man wiederum deren Properties traversieren müsste um an die gewünschten Stellen zu kommen. Eiderdaus, das ist schon alles nicht mehr so ganz ohne :gruebel:


Edit: Ich seh grad, dass die Richtung ja genau umgekehrt sein soll! Okay, dann eben eine Ableitung vom Chart und die Binding-Klamotte da rein. Da das Chart ja problemlos in seine Series gucken kann, vereinfacht das die Sache ungemein!

moelski 1. Dez 2009 09:24

Re: Objekteigenschaft übergeben?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin !

Ich habe jetzt mal ein Beispielprojekt erstellt. Es basiert auf einer Klasse mit 3 Listen.
es ist im moment nicht komplett ausprogrammiert - so fehlt die Überprüfung des Eigenschaftstyps komplett. Auch die eigenschaft an sich ist im Moment fest auf Text und die Komponente ist festgenagelt auf TEdit. Aber seis drum ...

Es zeigt wie es prinzipiell funktionieren könnte.

Zunächst mal erstellt man eine Instanz der Klasse. Dann kann man mittels Insert_Input Komponenten mit ihrer Property hinzufügen. Selbiges für die Ausgabe -> Insert_Output.

Jetzt noch mittels Insert_Match eintragen was denn von welchem Input auf welches Output soll (das würde später der User machen können).
Und am Ende ChangeDetect mit der Komponente aufrufen die sich geändert hat (da müsste man ggf. auch die Property mit übergeben ...).

Was sagt ihr zu dem Entwurf?

PS: Projekt ist in Delphi 2009 erstellt.

Alaitoc 1. Dez 2009 10:12

Re: Objekteigenschaft übergeben?
 
Also ich halte das für ziemlich unschön, besonders weil ich halt viel mit Patterns programmiere.

Ich poste hier einfach mal ein Pseudo-MVC Beispiel, welches ich hier schon angedeutet hatte:

Model und View:

Delphi-Quellcode:
Unit ModelView;

interface

type
  TObserver = class;

  TModel = class (TObject)
  public
    procedure Notify;
  end;

  TView = class (TObject)
  public
    procedure Update( Model: TModel); virtual; abstract;
  end;

implementation

uses
  Controller;

procedure TModel.Notify;
begin
  TController.Instance.Notify( Self );
end;
Observeritem:

Delphi-Quellcode:
unit Observeritem;

interface

uses
  ModelView;

type
  TObserverItem = class (TObject)
  private
    FModel: TModel;
    FView: TView;
  public
    property Model: TModel read FModel;
    property View: TView read FView;

    constructor Create(Model: TModel; View: TView);
  end;

implementation

constructor TObserverItem.Create(Model: TModel; View: TView);
begin
  FModel := Model;
  FView := View;
end;

end.
Observerlist:

Delphi-Quellcode:
unit ObserverList;

interface

uses
  ModelView,
  ObserverItem;

type
  TObserverList = class (TObjectlist)
  private
    function GetItems( Index: Integer): TObserverItem;
  public
    function Add( Model: TModel; View: TView): Integer;
    procedure Delete( Index: Integer);
    property Items[ Index: Integer]: TObserverItem read GetItems;
  end;

implementation

function TObserverList.Add( Model: TModel; View: TView): Integer;
begin
  Result := inherited Add( TObserverItem.Create( Model, View ) );
end;

procedure TObserverList.Delete( Index: Integer);
begin
  inherited Delete( Index );
end;

function TObserverList.GetItems( Index: Integer): TObserverItem;
begin
  Result := ( inherited Items[ Index ] ) as TObserverItem;
end;
Den Controller als Singleton kann ich gerade noch nicht posten, dafür fehlt mit atm die Zeit. Werde ich später nachholen, jedoch wird halt im Controller eine ObserverList verwaltet, wo jeweils die Models und Views bekannt gemacht werden. Bei einem Notify von einem Model würde er jedem View sagen das es ein Update ausführen soll und welches Model die Daten beinhaltet. Die Update-Methode des Views definiert man je nach Ansicht, indem man von der Basis-Klasse ableitet.

PS: Kann sein, dass hier noch was fehlt. Aber grundlegend sollte es das soweit sein bis auf den Controller. Schaue später nochmal über alles drüber.

MfG Alaitoc

moelski 1. Dez 2009 10:50

Re: Objekteigenschaft übergeben?
 
Moin Alaitoc,

wäre es machbar das du das mal in eine einfache Demoanwendung packst?
Also ähnlich wie bei mir z.B. einfach mit 2 Edits.

Alaitoc 1. Dez 2009 10:56

Re: Objekteigenschaft übergeben?
 
Moin,
kann ich gerne machen müsstest dich dann nur bis ~15:00 gedulden.
Atm bin ich hier bei mir leider ziemlich ausgelastet, aber
werde dann mal kurz was zusammenbasteln.

moelski 1. Dez 2009 10:59

Re: Objekteigenschaft übergeben?
 
Keinen Stress nicht.
Das ist im Moment für mich nur eine Machbarkeitsstudie ohne Zeitzwang. :-D

Aber schon mal vielen Dank für deine Hilfe :thumb:

Alaitoc 1. Dez 2009 14:40

Re: Objekteigenschaft übergeben?
 
Wirst dich wohl noch bis morgen begnügen müssen, da ich hier irgendwie grad kein Delphi hab bzw keinen Schlüssel
für meine CD :wall:

Naja hab ich wenigstens morgen in der Berufschule etwas sinnvolles zu tun *gg*

MfG Alaitoc

stahli 1. Dez 2009 19:03

Re: Objekteigenschaft übergeben?
 
Hallo moelski,

die Idee mit Zuordnung einer Komponente und einem Eigenschaftsnamen halte ich für machbar.
Die Frage ist, wie Du einem Endanwender (darum geht es?) die Auswahl ermöglichen willst.

Eine Trennung von Daten und GUI ist jedoch sicher immer sinnvoll.

Ich hatte in einem Projekt verbundene Datenkomponenten, die wiederum sichtbaren Komponenten zur Anzeige und Bearbeitung zugewiesen wurden. Die sichtbaren Komponenten konnten vom Endanwender über kleine Panels miteinander verbunden werden (wobei die wirklichen Zuordnungen nur in der Datenstruktur erfolgt sind).
(altes Beispiel hier als Video (bei 4. Minute) - keine Sorge, ich bin gerade an der Überarbeitung ;-) )

Meine Komponenten haben jedoch am Typ der Zielkomponente erkannt, was mit dieser bzw. mit d4en Daten passieren soll. Einen Property-Namen musste ich daher nicht mit übergeben.

Problematisch wird es übrigens, wenn die erzeugten Verbindungen bei Programmende gesichert und beim nächsten Programmstart wieder hergestellt werden sollen. Die Speicheradressen stimmen ja dann nicht mehr überein.

Stahli

Alaitoc 7. Dez 2009 07:17

Re: Objekteigenschaft übergeben?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Tut mir leid, dass ich mich erst so spät melde...
Habs jedoch irgendwie verdrängt die Demo hochzuladen. :wall:

Erklärung zum Projekt:

Also erstmal gibt es den Controller als Singleton. Dieser wird nur über die Instance Methode aufgerufen und ist halt solange vorhanden bis er nicht mehr gebraucht, bzw bis jede Instanz von ihm freigeben wird. Das habe ich hier in dem simplen Beispiel über eine globale Variable im Implementation - Teil geregelt. Ist sie noch nicht initialisiert erstelle ich sie mit CreateInstance, wenn sie dann erstellt ist gebe ich sie einfach immer per Result zurück.
Der Controller beinhaltet dann eine Beobachter-Liste, dort kann man jeweils ein Model und View anmelden und wieder abmelden.
Die Beobachterliste ist eigentlich nur eine Liste, wo pro Beobachter-Item jeweils ein Model und View dran hängen.
Zum Schluss hat der Controller noch eine Notify bzw. Aktualisierungsmethode mit einem Model als Übergabeparameter, da werden dann alle Views die an diesem Model hängen aktualsisiert ( Die Update-Methode des Views wird aufgerufen).

In dem abstrakten Model ist nur die Melde-Methode für den Controller vorhanden, also "Aktualisiere alle die mit mir regristiert sind". In dem konkreten Model sind dann noch zusätzlich die Daten vorhanden.

In dem abstrakten View ist nur eine abstrakte Update - Methode, die in den konkreten Views implementiert werden muss.
Die konkreten Views sind jeweils die Darstellungstypen, also z.b. Editfeld, Gauge, Label, etc...
Ich habe in meinem Beispiel darüber noch eine Klasse die als erstes ein MDI-Formular implementiert / erstellt, die Klassen die ich davon ableite beinhalten dann die individuelle Oberfläche.
Wichtig ist dann noch das das View das Model über eine Referenz kennt, da es sich dort die Daten herholt und auch über die Notify - Methode sagt das sich etwas geändert hat.

Ist eine Möglichkeit eine MVC zu implementieren, wobei ich halt auch mehrere Sachen weggelassen habe die nicht nötig sind.
Ist leider nicht ne 100% strikte Trennung, aber das nun noch zu erstellen... hätte meinen Zeitrahmen gesprengt.
Jedoch sollte es das sein was du wolltest...hoffe ich zumindest :freak:
Theorethisch sollte die Demo selbsterklärend sein, wobei unter Umständen der Singleton erst etwas verwirren könnte.

Bei Fragen einfach melden :)

MfG Alaitoc

Anmerkung: In der Demo habe ich die Erstellung der Models und Views einfach in FormCreate und FormDestroy reingepackt, das kann man um einiges besser machen... z.b. habe ich bei mir jeweils nocheinmal einen Handler der die Models und Views dann verwaltet.
Ganz wichtig dabei noch! Nicht zwischen den MDI-Childforms hin und her wechseln, einfach nur in dem Editfeld Daten eingeben...weil irgendwie haut er mir da immer ne EInvalidOperation raus und da ich noch nie MDI Sachen benutzt habe habe ich keine Ahnung woran es liegt

Edit findet immer Fehler x.x


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