Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Çoklu Olay Yöneticisi
#1
Amaç: Delphi'ye de C#'daki gibi çoklu olay tanımlayabilme özelliğini getirebilmek.

Elimizdeki yapı:

TTest = class
  private
   fClick: TNotifyEvent;

   function GetClick : TNotifyEvent;
   procedure SetClick(const Value : TNotifyEvent);
 public
   procedure Click;

   property OnClick : TNotifyEvent read GetClick write SetClick;
 end;

İstenen:
procedure TForm1.MyClick1(Sender: TObject);
begin
 ShowMessage('1');
end;

procedure TForm1.MyClick2(Sender: TObject);
begin
 ShowMessage('2');
end;

procedure TForm1.MyClick3(Sender: TObject);
begin
 ShowMessage('3');
end;

procedure TForm1.MyClick4(Sender: TObject);
begin
 ShowMessage('4');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 test : TTest;
begin
  test := TTest.Create;

  try
    test.OnClick := MyClick1;
    test.OnClick := MyClick2;
    test.OnClick := MyClick3;
    test.OnClick := MyClick4;
     test.Click;
  finally
     test.Free;
  end;
end;

Ekranda sırası ile; 1,2,3 ve 4 mesajlarını görmemiz gerekiyor. İlgili sınıfa istediğiniz gibi ekleme ve çıkartma yapabilirsiniz.

Not: 10 puan değerindedir.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#2
unit Unit4;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    type
   TTest = class
 private
  fClick: TNotifyEvent; //bunu dizi tanımladığım için kullanmadım ama ilk elemeanı yada son elemanı bunda tutabiliriz de
  count: integer;
   ArrfClick:Array of TNotifyEvent;
  function GetClick : TNotifyEvent;
  procedure SetClick(const Value : TNotifyEvent);
public
  procedure Click;

  property OnClick : TNotifyEvent read GetClick write SetClick;
end;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure MyClick1(Sender: TObject);
   procedure MyClick2(Sender: TObject);
   procedure MyClick3(Sender: TObject);
   procedure MyClick4(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;


var
 Form1: TForm1;

implementation

{$R *.dfm}
 function TTest.GetClick : TNotifyEvent;
 begin
  result:=ArrfClick[0];//1 elemanı veriyoruz buradan dizinin başlangıç adresini alabiliriz
 end;
  procedure TTest.SetClick(const Value : TNotifyEvent);
  begin
     inc(count);
   if length(ArrfClick)<count then setlength(ArrfClick,count*2); //Eğer dizi yetersizse büyütüyoruz
   //olay metodumuzu ekliyoruz
    ArrfClick[count-1]:=Value;   //burada bir for döngüsüyle kontrol edilip aynı adrese sahip fonksiyonu eklemeyebiliriz de
  end;

  procedure TTest.Click;
  var
  i:integer;
  begin
  for I := Low(ArrfClick) to High(ArrfClick) do
  begin
  if (@ArrfClick[i] <>nil)   // fonksiyon tanımlıysa çağırıyoruz
  then ArrfClick[i](self);

  end;


  end;

procedure TForm1.MyClick1(Sender: TObject);
begin
ShowMessage('1');
end;

procedure TForm1.MyClick2(Sender: TObject);
begin
ShowMessage('2');
end;

procedure TForm1.MyClick3(Sender: TObject);
begin
ShowMessage('3');
end;

procedure TForm1.MyClick4(Sender: TObject);
begin
ShowMessage('4');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
test : TTest;
begin
 test := TTest.Create;

 try
   test.OnClick := MyClick1;
   test.OnClick := MyClick2;
   test.OnClick := MyClick3;
   test.OnClick := MyClick4;
    test.Click;
 finally
    test.Free;
 end;
end;


end.
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#3
Ellerinize sağlık. Benim de çözümüm aşağıdaki gibidir:

  TTest = class
 private
   fEvents : TList<TNotifyEvent>;

   function GetClick : TNotifyEvent;
   procedure SetClick(const Value : TNotifyEvent);
 public
   constructor Create;
   destructor Destroy; override;

   procedure Click;

   property OnClick : TNotifyEvent read Getclick write SetClick;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TTest }

procedure TTest.Click;
var
 evt : TNotifyEvent;
 mtd : TMethod;
begin
 if fEvents.Count > 0 then
   for evt in fEvents do
   begin
     mtd.Code := @evt;
     mtd.Data := Self;
     TNotifyEvent(mtd)(Self);
   end;
end;

constructor TTest.Create;
begin
 fEvents := TList<TNotifyEvent>.Create;
end;

destructor TTest.Destroy;
begin
 fEvents.Clear;
 fEvents.Free;

 inherited;
end;

function TTest.GetClick: TNotifyEvent;
begin
 Result := fEvents.Items[0];
end;

procedure TTest.SetClick(const Value: TNotifyEvent);
begin
 fEvents.Add(Value);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 test : TTest;
begin
 test := TTest.Create;
 test.OnClick := MyClick1;
 test.OnClick := MyClick2;
 test.OnClick := MyClick3;
 test.OnClick := MyClick4;
 test.Click;
 test.Free;
end;

procedure TForm1.MyClick1(Sender: TObject);
begin
 ShowMessage('1');
end;

procedure TForm1.MyClick2(Sender: TObject);
begin
 ShowMessage('2');
end;

procedure TForm1.MyClick3(Sender: TObject);
begin
 ShowMessage('3');
end;

procedure TForm1.MyClick4(Sender: TObject);
begin
 ShowMessage('4');
end;
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
Bana "Observer Pattern"i hatırlattı
There's no place like 127.0.0.1
WWW
Cevapla
#5
Malumunuz ilgili pattern Delphi içinde pek çok yerde kullanılmaktadır. Örneğin componentlerin published property'lerinden biri bir başka component türünde ise, ilgili component'in container üzerinden silinmesi durumundan haberdar olunabilmesi için Notification metodu; ya da Owner mekanizması buna örnek gösterilebilir.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla

Konuyu Paylaş : facebook gplus twitter





Konuyu Okuyanlar: 1 Ziyaretçi