21 Aralık 2023 Perşembe

Örnek DI uygulaması 5 - Frame'lerin bir PageControl üzerinde çoklu gösterimi

 Önceki yazıdaki son durum üzerine şimdi ana ekrandaki sağ kısımda yer alan pnlForClientFrames adlı TPanel bileşenini kaldırıp yerine bir TPageControl bileşeni koyacağız. İsterseniz de TMoPageControl adlı benim üzerinde bir küçük ekleme yaptığım bileşeni kullanabilirsiniz. Bunun ek özelliği her sayfayı kapatmak için, üstteki tab başlığının sağında bir kapat düğmesi olmasıdır (x). Bu düğmenin bazı sayfaları kapatması engellenebilir. Koyduğumuz bu bileşenin adına pagesForFrames diyeceğim ben.

Yine formun üzerine bir TSplitter koyalım ve bunun Align=alLeft yapalım ardından pagesForFrames için Align=alClient yapalım.

Böylelikle şimdilik ana forma amacımıza uygun şekli vermiş oluyoruz. 

uInterfaces.pas kodunu açıp orada IDisplayOnPanel'i değiştirelim.

  IDisplayOnTabSheet = interface
    ['{B28B9829-CBF3-4629-9C3F-E3859497A185}']
    procedure DisplayOnTabSeet(const aTabSheet: TTabSheet);
  end;
Sonra 3 adet displayer'i buna uygun olarak değiştireceğiz.
unit uCustomersDisplayer;

interface
uses System.Classes, uInterfaces, Vcl.Controls, Vcl.ExtCtrls, View.Customers, Vcl.ComCtrls;

type
  TCustomersDisplayer = class(TInterfacedObject, IDisplayOnTabSheet)
  public
    procedure DisplayOnTabSheet(const aTabSheet: TTabSheet);
  end;

implementation

{ TCustomersDisplayer }

procedure TCustomersDisplayer.DisplayOnTabSheet(const aTabSheet: TTabSheet);
var frm : TframeCustomers;
begin
  frm := TframeCustomers.Create(aTabSheet);
  frm.Parent := aTabSheet;
  frm.Align := alClient;
end;

end.
Diğer 2 unit de buna benzer şekilde değiştirilecek.
Daha sonra sıra uRegistration.pas'a geliyor. Ondaki kayıt cümleciklerini de şu şekilde değiştireceğiz.
unit uRegistration;

interface

uses
  Spring.Container, uInterfaces;

procedure RegisterInterfaces(aMyConnection : IMyConnection);

implementation
uses
      uInventoriesDisplayer
    , uCustomersDisplayer
    , uSuppliersDisplayer
    ;

procedure RegisterInterfaces(aMyConnection : IMyConnection);
begin
  GlobalContainer.RegisterType<IDisplayOnTabSheet, TInventoriesDisplayer>('inventories');
  GlobalContainer.RegisterType<IDisplayOnTabSheet, TCustomersDisplayer>('customers');
  GlobalContainer.RegisterType<IDisplayOnTabSheet, TSuppliersDisplayer>('suppliers');


  GlobalContainer.RegisterInstance<IMyConnection>(aMyConnection, 'connection');

  GlobalContainer.Build;
end;

end.
Ve son olarak da View.MainForm'da değişiklik yapacağız. Oradaki IDisplayOnPanel'i IDisplayOnTabSheet olarak değiştireceğiz. Ve elbette bir iki ek daha olacak. Önce ats adlı TabSheet yaratıyoruz ve bunun PageControl'ü olarak pagesForFrames'i atıyoruz. ve DisplayOnTabSheet'e parametre olarak veriyoruz, son olarak ta PageControl'ün aktif sayfası haline getiriyoruz. Yani son
bastığımız sayfa öne çıkıyor.
procedure TMainForm.ViewClientFrame(const aFrameName: string);
var
  iScr : IDisplayOnTabSheet;
  ats : TTabSheet;
begin
  ats := TTabSheet.Create(pagesForFrames);
  ats.PageControl := pagesForFrames;

  iScr := GlobalContainer.Resolve<IDisplayOnTabSheet>(aFrameName);
  iScr.DisplayOnTabSheet(ats);
  pagesForFrames.ActivePage := ats;
end;

Ama buradaki ekran görüntüsünde de gördüğümüz gibi tabların başlıklarında hiçbir şey yazmıyor, çünkü biz bir değer atamadık. Şimdi onu da yapalım.
Öncelikle ViewMyBaseFrame'deki TframeMyBase'e bir virtual, abstract metot ekleyeceğiz.
...
...
    function GetCaption : string; virtual; abstract;
  end;
...
Amacımız bundan türetilen ekranlarda, bu metodun override edilmesini (ezilmesini) zorunlu kılarak her ekrana bir ekran adı verilmesini sağlamaktır. Bundan türeyen tüm ekranlar create edildiğinde eğer bu metodu override etmemişlerse program Abstract error verecektir ve açılmayacaktır.
unit View.Customers;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, View.MyBaseFrame, Data.DB, Vcl.Grids,
  Vcl.DBGrids, Vcl.ExtCtrls;

type
  TframeCustomers = class(TframeMyBase)
  private
    { Private declarations }
  protected
    function GetSqlClause : string; override;
  public
    function GetCaption : string; override;
  end;

var
  frameCustomers: TframeCustomers;

implementation

{$R *.dfm}

{ TframeCustomers }

function TframeCustomers.GetCaption: string;
begin
  Result := 'Müşteriler';
end;

function TframeCustomers.GetSqlClause: string;
begin
  Result := 'select * from Customer order by CustomerId';
end;

end.
Diğer ekranlarımız (View.Inventories, View.Suppliers) için de ayrı ayrı yapacağız aynı işi. 
Sonrasında tekrar Displayer'lerde değişiklik yapmamız gerekiyor.

...
procedure TCustomersDisplayer.DisplayOnTabSheet(const aTabSheet: TTabSheet);
var frm : TframeCustomers;
begin
  frm := TframeCustomers.Create(aTabSheet);
  frm.Parent := aTabSheet;
  frm.Align := alClient;
  aTabSheet.Caption := frm.GetCaption;
end;
Bu değişiklik diğer iki displayer'de de yapılmalı (uInventoriesDisplpayer.pas ve uSuppliersDisplayer.pas). 


Burada da görüldüğü gibi artık tab başlıklarını da yazıyor. 

Projenin bu şeklini şu linkten elde edebilirsiniz : DITest-4




































Hiç yorum yok:

Yorum Gönder