AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

eigenem Objekt Ereignisse hinzufügen

Ein Thema von Gargamel · begonnen am 13. Nov 2008 · letzter Beitrag vom 16. Nov 2008
Antwort Antwort
Gargamel

Registriert seit: 19. Mär 2007
171 Beiträge
 
#1

eigenem Objekt Ereignisse hinzufügen

  Alt 13. Nov 2008, 21:37
Hi

Ich beschäftige mich gerade etwas näher mit OOP. Funktioniert auch soweit ganz gut. Jetzt hätte ich gern gewußt, wie man seinem eigenen Objekt Ereignisse spendieren kann.
In der Hilfe stand irgendwas von TNotifyEvent, nur leider ist da bei mir Feierabend.
Nehmen wir einfach mal an, daß ein Ereignis ausgelöst werden soll, wenn der Name der Person geändert wird. Was müßte ich da machen?

Delphi-Quellcode:
unit Unit_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

  TPerson = class
  private
    Name:string;
    FirstName:string;
  public
    constructor Create();
    procedure setName(newName:string);
    procedure setFirstName(newFirstname:string);
    function getName():string;
    function getFirstName():string;
  end;

var
  Form1: TForm1;
  Person:TPerson;

implementation

{$R *.dfm}

constructor TPerson.Create;
begin
  inherited create;
  Name:='';
  FirstName:='';
end;

procedure TPerson.setName(newName:string);
begin
  Name:=newName;
end;

procedure TPerson.setFirstName(newFirstName:string);
Begin
  FirstName:=newFirstName;
End;

function TPerson.getName():string;
Begin
  result:=Name;
end;

function TPerson.getFirstName():string;
Begin
  result:=FirstName;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Person:=TPerson.Create;
  Person.setName('Test_Nachname');
  Person.setFirstName('Test_Vorname');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Listbox1.Clear;
  Listbox1.Items.add(Person.getName());
  Listbox1.Items.add(Person.getFirstName());
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

Re: eigenem Objekt Ereignisse hinzufügen

  Alt 13. Nov 2008, 22:06
Hi,

so muss das aussehen
Delphi-Quellcode:
unit Unit_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure NameWurdeGeaendert1( Sender : TObject );
    procedure NameWurdeGeaendert2( Sender : TObject; VName, NName : string );
  public
    { Public-Deklarationen }
  end;
  
  TNotifyPersonEvent = procedure( Sender : TObject; VName, NName : string ) of object;

  TPerson = class
  private
    FNName:string;
    FVName:string;
    FOnNameChange1 : TNotifyEvent; // Definition für TNotifyEvent = procedure( Sender : TObject ) of object;
    FOnNameChange2 : TNotifyPersonEvent;
    procedure SetVName( Value : string );
    procedure SetNName( Value : string );
    procedure SetOnNameChange1( Value : TNotifyEvent );
    procedure SetOnNameChange2( Value : TNotifyPersonEvent );
  public
    // Mit property geht das viel schöner :-)
    // den private Bereich mal komplett leer lassen, dann
    // einfach nur diese Zeilen eintippen und dann
    // Shift-Ctrl-C drücken (Code-Completion) und staunen ;-)
    property VName : string read FVName write SetVName;
    property NName : string read FNName write SetNName;
    property OnNameChange1 : TNotifyEvent read FOnNameChange1 write SetOnNameChange1;
    property OnNameChange2 : TNotifyPersonEvent read FOnNameChange1 write SetOnNameChange1;
    constructor Create;
  end;

var
  Form1: TForm1;
  Person:TPerson;

implementation

{$R *.dfm}

constructor TPerson.Create;
begin
  inherited Create;
  FNName := '';
  FVName := '';
end;

procedure TPerson.SetVName( Value : string );
begin
  FVName := Value;
  if Assigned( FOnChangeName1 ) // ist das Gleiche wie: if FOnChangeName1 <> nil
  then
    FOnChangeName1( Self );
  if Assigned( FOnChangeName2 )
  then
    FOnChangeName2( Self, FVName, FNName );
end;

procedure TPerson.SetNName( Value : string );
begin
  FNName := Value;
  if Assigned( FOnChangeName1 )
  then
    FOnChangeName1( Self );
  if Assigned( FOnChangeName2 )
  then
    FOnChangeName2( Self, FVName, FNName );
end;

procedure TPerson.SetOnNameChange1( Value : TNotifyEvent );
begin
  FOnNameChange1 := Value;
end;

procedure TPerson.SetOnNameChange2( Value : TNotifyPersonEvent );
begin
  FOnNameChange2 := Value;
end;

procedure TForm1.NameWurdeGeaendert1( Sender : TObject );
begin
  ShowMessage( 'Der Name wurde geändert!' );
end;

procedure TForm1.NameWurdeGeaendert2( Sender : TObject; VName, NName : string );
begin
  ShowMessage( 'Der Name wurde auf ' + VName + ' ' + NName + ' geändert!' );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Person:=TPerson.Create;

  Person.OnNameChange1 := NameWurdeGeaendert1;
  Person.OnNameChange2 := NameWurdeGeaendert2;
  
  Person.setName('Test_Nachname');
  Person.setFirstName('Test_Vorname');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Listbox1.Clear;
  Listbox1.Items.add(Person.getName());
  Listbox1.Items.add(Person.getFirstName());
end;

end.
cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Gargamel

Registriert seit: 19. Mär 2007
171 Beiträge
 
#3

Re: eigenem Objekt Ereignisse hinzufügen

  Alt 13. Nov 2008, 22:31
Na das nenne ich mal eine prompte Bedienung. Einige Zeilen sind mir nicht ganz klar, aber das werde ich noch herausfinden.

Vielen Dank
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

Re: eigenem Objekt Ereignisse hinzufügen

  Alt 13. Nov 2008, 22:35
Zitat von Gargamel:
Na das nenne ich mal eine prompte Bedienung. Einige Zeilen sind mir nicht ganz klar, aber das werde ich noch herausfinden.

Vielen Dank
Bitte bitte, sonst frag halt welche ... oder markiere die Zeilen mit einem Fragezeichen ...

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Gargamel

Registriert seit: 19. Mär 2007
171 Beiträge
 
#5

Re: eigenem Objekt Ereignisse hinzufügen

  Alt 16. Nov 2008, 15:47
Hi

Ja, ein paar Sachen sind mir noch nicht ganz klar.

Zeile 24: Wozu wurde TNotifyPersonEvent deklariert?

Zeile 44: Müßte das nicht FOnNameChange2 und SetOnNameChange2 lauten?


Zeile 41-44:
Ich vermute, daß es property wegen dem Objektinspektor gibt, damit eine Wertzuweisung intern einen Funktionsaufruf zur Folge hat (via read und write hinter der property-Eigenschaft).

Zeile 109: Hier wird die Funktion definiert, die bei Ereignis XY ausgeführt werden soll?


Das Zusammenspiel von SetVName, SetOnNameChange1 und FOnNameChange ist mir noch nicht ganz klar.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

Re: eigenem Objekt Ereignisse hinzufügen

  Alt 16. Nov 2008, 16:24
Zitat von Gargamel:
Hi

Ja, ein paar Sachen sind mir noch nicht ganz klar.
Zitat von Gargamel:
Zeile 24: Wozu wurde TNotifyPersonEvent deklariert?
Um einen eigenen EventType zu deklarieren. Mit TNotifyEvent kann ich nur Sender als Parameter übergeben.
Will ich mehr übergeben, dann macht man das so. Mit diesem Event kann ich also hier auch gleich VName und NName übergeben. (so geschieht in Zeile 82)

Zitat von Gargamel:
Zeile 44: Müßte das nicht FOnNameChange2 und SetOnNameChange2 lauten?
ja bitte ändern

Zitat von Gargamel:
Zeile 41-44:
Ich vermute, daß es property wegen dem Objektinspektor gibt, damit eine Wertzuweisung intern einen Funktionsaufruf zur Folge hat (via read und write hinter der property-Eigenschaft).
Nicht nur das, dadurch kann ich steuern, ob eine Eigenschaft z.b. nur lesend oder nur schreibend ist, und ich kann auf diese Ereignisse auch noch reagieren. Der Vorteil ist, dass bei der Benutzung der Klasse einfach einer anscheinlichen Variablen der Klasse ein Wert zugewiesen wird, was die Programmierung wesentlich erleichtert. Also statt GetVariable und SetVariable arbeite ich einfach mit Variable und fertig.

eine Property kann ich auch wie folgt deklarieren:
Delphi-Quellcode:
private
  FVar : integer;
  function GetVar : integer;
  procedure SetVar( Value : integer);
public
  property Var1 : integer read GetVar write SetVar; // Lesen und Schreiben via func/proc
  property Var2 : integer read FVar; // Nur Lesen direkt
  property Var3 : integer write FVar; // Nur Schreiben direkt
  property Var4 : integer read GetVar; write FVar; // Lesen via func, Schreiben direkt
Zitat von Gargamel:
Zeile 109: Hier wird die Funktion definiert, die bei Ereignis XY ausgeführt werden soll?
Nein, definiert wird die in Zeile 95.
In Zeile 109 wird diese procedure an die Klasse gehängt.
Ausgeführt wird die, wenn die Klasse den Event feuert (Zeile 68/79), darum wird auch in Zeile 66/77 überprüft, ob für dieses Event auch ein Ziel angegeben wurde.

Zitat von Gargamel:
Das Zusammenspiel von SetVName, SetOnNameChange1 und FOnNameChange ist mir noch nicht ganz klar.
Wenn Person.VName := 'Peter' ausgeführt wird, dann wird die proc TPerson.SetVName( 'Peter' ) aufgerufen.
Hier wird der Variablen TPeter.FVName der Wert 'Peter' zugewiesen.
Dann werden die Events gefeuert.

Wenn du das Programm mal ausführst, dann solltest du eigentlich sehen, was da passiert.
Vor allem kommentiere doch mal wahlweise die Zeile 109 und 110 aus und schau was passiert.

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:25 Uhr.
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