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 Eigene Ereignisse für ein Object (https://www.delphipraxis.net/182053-eigene-ereignisse-fuer-ein-object.html)

Captnemo 26. Sep 2014 13:21

Delphi-Version: 5

Eigene Ereignisse für ein Object
 
Hi,

bei der Erstellung einer Komponente stoße ich doch immer wieder auf Dinge, die ich noch nie gemacht habe. Deswegen muß ich mal wieder Fragen.
Für viele von euch sicherlich selbsterklärend, aber ich hab's noch nicht kapiert.

Haben eine grafische Komponente, z.B. eine Listbox.
Diese MyListbox hat ja Items. Im meinem Fall sind die Items jetzt mal ein ganz simple TObject, organisiert in einer TCollection.

Jetzt möchte ich jedem Object ein eigenes Ereignis verpassen...als Beispiel vielleicht ein OnChanged (ob's das jetzt schon gibt ist ja egal, ist ja nur ein Beispiel), das ausgelöst werden soll, wenn sich an irgendeiner Property was ändert. Diesem Ereignis soll in der MyListbox dann eine Procedure hinzugefügt werden. Aber ich will auch noch Parameter mit übergeben. Also z.B. OnChanged(Sender: TObject; ItemIndex: Integer);

Ich hab mal ein bischen in den Delphi-Sourcecodes geguckt, um rauszukriegen, wie das da gemacht wird, aber da werde ich von der Menge erschlagen.
Ich bräuchte mal ein Beispiel, wie sowas in der Unit in der die Items definiert sind, aussehen muß.

-=ZGD=- 26. Sep 2014 13:34

AW: Eigene Ereignisse für ein Object
 
Ich glaube, du musst nur einen eigenen Callback dafür definieren

Delphi-Quellcode:
type TOnItemChange = procedure(Sender: TObject; ItemIndex: Integer) of object
Dann im Private deiner Komponente:

Delphi-Quellcode:
private
fOnItemChange: TOnItemChange;

public
 property OnItemChange: TOnItemChange read fOnItemChange write fOnItemChange;
und von außen kannst du es mit einer eigenen Prozedur beschreiben

Delphi-Quellcode:
procedure OnItemChange(Sender: TObject; ItemIndex: Integer);

DeineKomponente.OnItemChange:= OnItemChange
Ich hoffe, dass du genau danach gesucht hast..

mjustin 26. Sep 2014 13:41

AW: Eigene Ereignisse für ein Object
 
Zitat:

Zitat von -=ZGD=- (Beitrag 1273949)
von außen kannst du es mit einer eigenen Prozedur beschreiben

Delphi-Quellcode:
procedure OnItemChange(Sender: TObject; ItemIndex: Integer);

Die OnItemChange Prozedur passt nicht zur Methodensignatur. Mit dieser hier würde es gehen:

Delphi-Quellcode:
procedure TMyForm.OnItemChange(Sender: TObject; ItemIndex: Integer);

Stevie 26. Sep 2014 13:57

AW: Eigene Ereignisse für ein Object
 
Ich würde hier ein Konzept ähnlich der MSDN-Library durchsuchenBindingList vorschlagen.
Jedes Element, was der Liste hinzugefügt wird (im Notify der Liste), verknüpft sich mit dem Eventhandler der Liste (abhängen beim Remove nicht vergessen).
Und die Liste leitet diese Events an dein Control weiter.

Captnemo 29. Sep 2014 07:24

AW: Eigene Ereignisse für ein Object
 
Okay, das ist soweit klar.

Aber ich muß ja noch irgendwo einen "Auslöser" definieren, der das OnItemChange-Ereignis auslöst.
Ich will ja keine geerbten Ereignisse, sondern ein neues definieren, z.B. OnSelectChange.

Ich habe das jetzt so gelöst (nicht Themarelevante Codeabschnitte habe ich mal rausgeschnitten):

Delphi-Quellcode:
Type
  TOnSelectChange=procedure(Sender: TObject; ItemIndex: Integer) of object;

Type
  TEntry=class(TCollectionItem)
  private
    FSelected: Boolean;
    FOnSelectChange: TOnSelectChange;
    procedure SetSelected(const Value: Boolean);
  public
    constructor Create(Collection: TCollection; EntryTypes: TEntryTypes);
    destructor Destroy;
  published
    property Selected: Boolean read FSelected write SetSelected;
    property OnSelectChange: TOnSelectChange read FOnSelectChange write FOnSelectChange;
  end;

...

implementation

{ TEntries }

procedure TEntry.SetSelected(const Value: Boolean);
var
  OldValue: Boolean;
begin
  if not Assigned(FOnSelectChange) then Exit;
  OldValue:=FSelected;
  FSelected := Value;
  if (FSelected<>OldValue) then
    OnSelectChange(self, self.Index);
end;
Macht man das so?

Jetzt habe ich noch ein Problem damit. Die oben definiert Klasse TEntry bzw. deren Collection ist ja Bestandteil meiner Komponente. In der "Main"-Unit dieser Komponente wird diese Collection ja erzeugt, und es können über den OI Entries hinzugefügt werden. Jedes´m Item soll dem OnSelectChange-Ereignis eine entsprechende Procedure in der Main-Unit hinzugefügt werden. Grund ist der, dass ich z.B. in der Main erkenne, wann sich ein SelectState ändert, und ein Repaint ausgelöst werden muß.

Jetzt muß ich aber nach dem Create der Komponente jedem bereits vorhandenen Items auch diese Procedure aus der Main-Unit dem OnSelectChange-Ereignis zuweisen. Wo mache ich das? Wann werden die Items, die im IO definiert wurden tatsächlich zur Runtime erzeugt?

Bjoerk 29. Sep 2014 09:02

AW: Eigene Ereignisse für ein Object
 
Verfügt TEntryList über ein Ereignis OnAddItem? Da könnte man es relativ bequem setzen?

Delphi-Quellcode:
procedure TMyForm.SelectChange(..);
begin
  FMyEntryList.Invalidate;
end;

procedure TMyForm.MyEntryListOnAddItem(..);
begin
  FMyEntryList.Last.OnSelectChange := SelectChange;
end;

Captnemo 29. Sep 2014 09:40

AW: Eigene Ereignisse für ein Object
 
Ich habe zwar ein Function Add
Delphi-Quellcode:
type
  TEntries=class(TCollection)
  private
    FonEntryAdd: TOnEntryAdd;
    function getItem(index: Integer): TEntry;
    procedure setItem(index: Integer; const Entry: TEntry);
  public
    property Items[index: Integer]: TEntry read getItem write setItem; default;
    function Add: TEntry; virtual;
    property OnEntryAdd: TOnEntryAdd read FonEntryAdd write FonEntryAdd;
  end;

implementation

{ TEntries }

function TEntries.Add: TEntry;
begin
  Result := TEntry(inherited Add);
  if Assigned(FonEntryAdd) then
    self.OnEntryAdd(Self);
end;
Aber die wird nach dem Start nie aufgerufen, also mit den im OI vordefinierten Entries.

Zoot 29. Sep 2014 10:00

AW: Eigene Ereignisse für ein Object
 
Zitat:

Zitat von Captnemo (Beitrag 1274167)
Ich habe zwar ein Function Add


Aber die wird nach dem Start nie aufgerufen, also mit den im OI vordefinierten Entries.

Versuchs mal mit dem Zauberwort "override" statt "virtual".

Captnemo 29. Sep 2014 10:14

AW: Eigene Ereignisse für ein Object
 
Zitat:

Zitat von Zoot (Beitrag 1274171)
Zitat:

Zitat von Captnemo (Beitrag 1274167)
Ich habe zwar ein Function Add


Aber die wird nach dem Start nie aufgerufen, also mit den im OI vordefinierten Entries.

Versuchs mal mit dem Zauberwort "override" statt "virtual".

Geht nicht. Dann bekomme ich den Fehler: E2170 Ein nichtvirtuelle Methode kann nicht überschrieben werden.

Bjoerk 29. Sep 2014 10:39

AW: Eigene Ereignisse für ein Object
 
Diese OnEntryAdd wird dir für deine Zwecke (Verfügbar schon zur Designzeit ect.) nicht viel bringen. Such mal bei TCollection im OI ein entsprechendes Ereignis. Und spendier deinen desctructors mal ein override;


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