Delphi Can

Orjinalini görmek için tıklayınız: Butonlarla Kategori ve AltKategori Yapma
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Sayfalar: 1 2 3 4
Peki bu işi kategori olayını button ile yapabilir miyiz?
Butonlarla sonunda istediğim olayı yapabildim...
Forum create olayına aşağıdaki kodu yazdım;
procedure TForm1.FormCreate(Sender: TObject);
var
 NewButton: TButton;
 i:integer;
begin
with Form1.MyQueryKategori do
begin
Close;
SQL.Clear;
SQL.Add('select * from TABLE_CATEGORY where SHOW_MAIN=Big GrinefUserId');
ParamByName('DefUserId').AsInteger := 1;
OPEN;
i:=0;
while NOT(MyQueryKategori.EOF) do begin

 NewButton := TButton.create(self);
 with NewButton do
 begin
   Height :=  (Panel1.Height - 20 ) div MyQueryKategori.RecordCount;
   Width  := Panel1.Width - 10;
   Left   :=  (Width - Width )+ 5 ;
 Top    := i * (Panel1.Height div MyQueryKategori.RecordCount) + MyQueryKategori.RecordCount ;
 Parent := Panel1;
 OnClick := CustomButtonClick;
 Caption := MyQueryKategoriCatname.AsString;
 end;
 Inc(i);
 MyQueryKategori.Next;
 end;
Close;
end;
end;


İlgili oluşturulan kategori butonuna tıklanınca da çalışması için aşağıdaki kodu yazdım;

procedure TForm1.CustomButtonClick(Sender: TObject);
var
SelectedItem:String;
i:integer;
 NewButton: TButton;
begin
SelectedItem:= TButton(Sender).caption;
with Form1.MyQueryUrun do
begin
Close;
SQL.Clear;
SQL.Text := 'SELECT * FROM TABLE_PRODUCTS INNER JOIN TABLE_CATEGORY on TABLE_PRODUCTS.CatID = TABLE_CATEGORY.ID WHERE `Catname` = "' + SelectedItem + '" ';
Open;
i:=0;
while NOT(MyQueryUrun.EOF) do begin
 NewButton := TButton.create(self);
 with NewButton do
 begin
   Height :=  (Panel2.Height - 20 ) div MyQueryUrun.RecordCount;
   Width  := Panel2.Width - 10;
   Left   :=  (Width - Width )+ 5 ;
 Top    := i * (Panel2.Height div MyQueryUrun.RecordCount) + MyQueryUrun.RecordCount ;
 Parent := Panel2;
 OnClick := CustomButtonClick;
 Caption := MyQueryUrunProdName.AsString;
 end;

 Inc(i);
 MyQueryUrun.Next;
 end;
Close;
end;
end;

2 problemim kaldı... Birincisi hangi tuşa tıklandığını nasıl algılayıp işlem yapabilirim? Yani sigara tuşuna basıldığında programa adet fiyatını, depositosunu vs göndermem lazım.. İkinci problem ise kategori tuşuna tıkladıktan sonra oluşturulan butonlar 2. kategori tuşuna bastığımda silinmesi gerekiyor.. Bunları yapamadım :S

İkinci problemimi çözdüm

while  Panel2.ControlCount > 0 do
Panel2.Controls[0].Free;

Bu şekilde... 

SimaWB arkadaşın söylediği tag olayına bir yoğunlaşayım bakalım. Onu da halledersem problemim kalmayacak inşallah
@akissoftware, illa butonlarla devam etmek istersen yukarıda bahsedildiği gibi butonların Tag özelliğinde veri saklama yoluna gidebilirsin. 
Basit bir örnek vermeye çalışayım:
Buton içinde Id ve Name değerleri saklamak istediğimizi düşünelim. Öncelikle bununla ilgili sınıfı oluşturmalıyız:
TVeri = class
   id: Integer;
   Name: String;
 end;

Sonra bu sınıfa ait bir örneği Button'un Tag'inde saklayalım:
var
 veri: TVeri;
begin
 veri := TVeri.Create;
 veri.id := 100;
 veri.Name := 'SimaWB';
 Button1.Tag := Integer(veri);

Daha sonra bu veriyi okumak istediğimizde:
var
 veri: TVeri;
begin
 veri := TVeri(Button1.Tag);
 Caption := veri.Name;
 veri.Free;

Buradaki Free'ye dikkat Wink

Ben butonda veri saklamak istesem şöyle yapardım:
http://www.delphican.com/bilesen-icinde-...-2848.html
Smile
Tam olarak istedigin hersey bu konuda var
http://www.delphican.com/for-ile-olustur...lusturulan
Bak ornek vereyim aynisini yapacaksin


 livebutton:=Tbutton.create(self);
 livebutton.top:=100;
 livebutton.left:=100;
 livebutton.height:=45;
 livebutton.width:=100;
 livebutton.Font.Size:=15;
 livebutton.parent:=(form2.ScrollBox1);
 Form2.ScrollBox1.Height:=livebutton.height*(Length(EnigmaAPI.Categories.live));
 livebutton.Align:=altop;
 livebutton.tag:=strtoint(EnigmaAPI.Categories.live[i].category_id);
 livebutton.caption:=  EnigmaAPI.Categories.live[i].category_name;
 livebutton.OnClick:= LiveButtonlarClick;
     
Özetle yukarıdaki kodunuzun en altına aşağıdaki satırı ekleyip bu isimde bir procedure tanımlamanız gerekiyor.
  livebutton.OnClick := LiveButtonlarClick; 

Daha sonra aşağıdaki gibi bir kontrol yazabilirsiniz.
procedure TForm1.LiveButtonlarClick(Sender: TObject);
begin
  if Sender is TButton then
  begin
   if TButton(Sender).Tag = 584 then
   begin
    ShowMessage('"'+TButton(Sender).Caption+'" butonuna tıkladınız.');
   end;
  end;
end;   
Merhaba.

Değerlendirmem odur ki, kategori / alt kategori konusunda mantık kurma aşamasında takıldınız
Boyutlandırmada olduğunu sanmıyorum. 

:idea: Bu nedenle hem yeniden boyutlandırma, TScrollBox içinde dinamik dağıtma, her tıklamada yeni dinamik alt kategori butonu türetme vs.
 tümünü içeren bir örnek hazırladım. 

:arrow: Proje ve DB mesaj ekinde indirilebilir şekilde yer alıyor.


n4r5pulrcqxuovdyvgxh.gif
Kaynak Kodlar Aşağıda...

Var
  xAdoConnection : TAdoConnection;
  xDataSource    : TDataSource;
  xAdoQuery      : TAdoQuery;

  xDataUrunSource: TDataSource;
  xAdoUrunQuery  : TAdoQuery;

Const
  xADO  = 'Provider=Microsoft.Jet.OLEDB.4.0;'
          + 'Data Source=%s;'
          + 'Mode=Share Deny None;'
          + 'Persist Security Info=False;'
          + 'Jet OLEDB:Database Password=%s;'
          ;

procedure TForm1.FormCreate(Sender: TObject);
Var
  strData : String;
begin
  ReportMemoryLeaksOnShutdown := True;

  strData := ExcludeTrailingPathDelimiter( ExtractFilePath(ParamStr(0)) ) + '\DATA\filmdb.mdb';

  xAdoConnection := TAdoConnection.Create(nil);

  With xADOConnection do begin
    Connected          := False;
    LoginPrompt        := False;
    ConnectionString   := Format( xAdo, [ strData, '' ] );
  end;

  xDataSource              := TDataSource.Create(nil);
  xAdoQuery                := TAdoQuery.Create(nil);
  xDataSource.DataSet      := xADOQuery;

  xDataUrunSource          := TDataSource.Create(nil);
  xAdoUrunQuery            := TAdoQuery.Create(nil);
  xDataUrunSource.DataSet  := xAdoUrunQuery;

  DBGrid1.DataSource := xDataSource;
  DBGrid2.DataSource := xDataUrunSource;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  ButonaBasildi(nil);
end;

Var
  xButonlar: Array of TButton;
  xKategori: String = 'M_Year';
  xKatSira : Word   = 1; // 1: M_Year, 2: M_Runtime, 3:M_Lang
  xWhere   : String = '';
  xGroupBy : String = '';

procedure TForm1.KategoriButtonOlustur( strAlanAdi: String; aScrollBox:TScrollBox; boolSadeceTazele:Boolean = False );
Const
  Boy         = 200;
  Yukseklik   = 30;
  SolMargin   = 10;
  TepeMargin  = 10;
  Aralik      = 05;
var
  i, Satir, Sutun: Integer;
begin
  // -1,0
  if boolSadeceTazele AND ( NOT xAdoQuery.Active ) then
  begin
    EXIT; // ilk çalışma anı
  end;

  if NOT boolSadeceTazele then begin
    With xADOQuery do begin
      Connection := xADOConnection;
      SQL.Clear;
      if strAlanAdi = '!!!ButonTemizle' then begin
        SQL.Add('SELECT 1 as [Boşalttık] FROM Movies');
        SQL.Add('WHERE 1=0'); // Sonuç boş dönsün istediğimizde FIELD adı '!!!ButonTemizle' yaz yeter...
      end else
      begin
        SQL.Add('SELECT '+strAlanAdi+', Count(*) as [Adet] FROM Movies');
        SQL.Add('WHERE 1=1');
        SQL.Add( xWhere   );
        SQL.Add( xGroupBy );
        SQL.Add('ORDER BY '+ strAlanAdi );
      end;
      Active := True;
    end;
  end;

  // Önce mevcut butonları silelim...
  if High( xButonlar ) >=  Low( xButonlar )
  then for i := Low( xButonlar ) to High( xButonlar )
       do xButonlar[i].Free;

  Application.ProcessMessages;
  SetLength( xButonlar, 0 );

  i     := 0;
  Satir := 0;
  Sutun := -1;
  xAdoQuery.First;
  while NOT xAdoQuery.EOF do
  begin
    inc(i);
    SetLength( xButonlar, i );
    xButonlar[i-1] := TButton.Create(nil);
    With xButonlar[i-1] do begin
      Width   := Boy;
      Height  := Yukseklik;
      Caption := xAdoQuery.Fields[0].AsString + ': ( ' + xAdoQuery.Fields[1].AsString + ' )' ;
      Parent  := aScrollBox;
      OnClick := ButonaBasildi;

      inc(sutun);
      if aScrollBox.Width < ( SolMargin + ( Sutun * (Width + Aralik) ) + (Width + Aralik))then
      begin
        inc( Satir );
        Sutun := 0;
      end;

      Left    := SolMargin  + (Sutun * (Width  + Aralik));
      Top     := TepeMargin + (Satir * (Height + Aralik));
    end;
    xAdoQuery.Next;
  end;

end;

procedure TForm1.ButonaBasildi( aButton:TObject );
var
  strCaption : String;
begin
  if aButton = nil then
  begin
     xKatSira := 1;
     xWhere   := '';
     xGroupBy := 'GROUP BY M_Year';
  end else
  begin
    strCaption := StringReplace( TButton(aButton).Caption, '&', '', [rfReplaceAll] );
    strCaption := Trim( Copy( strCaption, 1, Pos(': (', strCaption )-1) );

    inc( xKatSira );
    if xKatSira > 4 then xKatSira := 1;
  end;

  case xKatSira of
  1: begin
       xWhere   := '';
       xGroupBy := 'GROUP BY M_Year';
       KategoriButtonOlustur( 'M_Year',    ScrollBox1 );
       UrunListele();
     end;
  2: begin
       xWhere := xWhere + ' AND M_Year = ' + QuotedStr( strCaption );
       xGroupBy := 'GROUP BY M_Runtime';
       KategoriButtonOlustur( 'M_RunTime', ScrollBox1 );
       UrunListele();
     end;
  3: begin
       xWhere := xWhere + ' AND M_Runtime = ' + QuotedStr( strCaption );
       xGroupBy := 'GROUP BY M_Lang';
       KategoriButtonOlustur( 'M_Lang',    ScrollBox1 );
       UrunListele();
     end;
  4: begin
       xWhere := xWhere + ' AND M_Lang = ' + QuotedStr( strCaption );
       KategoriButtonOlustur( '!!!ButonTemizle',    ScrollBox1 );
       UrunListele();
     end;
  end;
end;

procedure TForm1.UrunListele;
begin
  With xAdoUrunQuery do begin
    Connection := xADOConnection;
    SQL.Clear;
    SQL.Add('SELECT * FROM Movies');
    SQL.Add('WHERE 1=1');
    SQL.Add( xWhere   );
    Active := True;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  xAdoConnection.Connected := False;

  xAdoConnection.Free;
  xAdoQuery.Free;
  xAdoUrunQuery.Free;

  xDataSource.Free;
  xDataUrunSource.Free;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  KategoriButtonOlustur( '', ScrollBox1, True ); // Sadece butonları tazele
end;

(09-11-2018, Saat: 00:19)mrmarman Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba.

Değerlendirmem odur ki, kategori / alt kategori konusunda mantık kurma aşamasında takıldınız
Boyutlandırmada olduğunu sanmıyorum. 

Idea Bu nedenle hem yeniden boyutlandırma, TScrollBox içinde dinamik dağıtma, her tıklamada yeni dinamik alt kategori butonu türetme vs.
 tümünü içeren bir örnek hazırladım. 

Arrow Proje ve DB mesaj ekinde indirilebilir şekilde yer alıyor.


n4r5pulrcqxuovdyvgxh.gif
Kaynak Kodlar Aşağıda...

Var
  xAdoConnection : TAdoConnection;
  xDataSource    : TDataSource;
  xAdoQuery      : TAdoQuery;

  xDataUrunSource: TDataSource;
  xAdoUrunQuery  : TAdoQuery;

Const
  xADO  = 'Provider=Microsoft.Jet.OLEDB.4.0;'
          + 'Data Source=%s;'
          + 'Mode=Share Deny None;'
          + 'Persist Security Info=False;'
          + 'Jet OLEDBBig Grinatabase Password=%s;'
          ;

procedure TForm1.FormCreate(Sender: TObject);
Var
  strData : String;
begin
  ReportMemoryLeaksOnShutdown := True;

  strData := ExcludeTrailingPathDelimiter( ExtractFilePath(ParamStr(0)) ) + '\DATA\filmdb.mdb';

  xAdoConnection := TAdoConnection.Create(nil);

  With xADOConnection do begin
    Connected          := False;
    LoginPrompt        := False;
    ConnectionString   := Format( xAdo, [ strData, '' ] );
  end;

  xDataSource              := TDataSource.Create(nil);
  xAdoQuery                := TAdoQuery.Create(nil);
  xDataSource.DataSet      := xADOQuery;

  xDataUrunSource          := TDataSource.Create(nil);
  xAdoUrunQuery            := TAdoQuery.Create(nil);
  xDataUrunSource.DataSet  := xAdoUrunQuery;

  DBGrid1.DataSource := xDataSource;
  DBGrid2.DataSource := xDataUrunSource;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  ButonaBasildi(nil);
end;

Var
  xButonlar: Array of TButton;
  xKategori: String = 'M_Year';
  xKatSira : Word   = 1; // 1: M_Year, 2: M_Runtime, 3:M_Lang
  xWhere   : String = '';
  xGroupBy : String = '';

procedure TForm1.KategoriButtonOlustur( strAlanAdi: String; aScrollBox:TScrollBox; boolSadeceTazele:Boolean = False );
Const
  Boy         = 200;
  Yukseklik   = 30;
  SolMargin   = 10;
  TepeMargin  = 10;
  Aralik      = 05;
var
  i, Satir, Sutun: Integer;
begin
  // -1,0
  if boolSadeceTazele AND ( NOT xAdoQuery.Active ) then
  begin
    EXIT; // ilk çalışma anı
  end;

  if NOT boolSadeceTazele then begin
    With xADOQuery do begin
      Connection := xADOConnection;
      SQL.Clear;
      if strAlanAdi = '!!!ButonTemizle' then begin
        SQL.Add('SELECT 1 as [Boşalttık] FROM Movies');
        SQL.Add('WHERE 1=0'); // Sonuç boş dönsün istediğimizde FIELD adı '!!!ButonTemizle' yaz yeter...
      end else
      begin
        SQL.Add('SELECT '+strAlanAdi+', Count(*) as [Adet] FROM Movies');
        SQL.Add('WHERE 1=1');
        SQL.Add( xWhere   );
        SQL.Add( xGroupBy );
        SQL.Add('ORDER BY '+ strAlanAdi );
      end;
      Active := True;
    end;
  end;

  // Önce mevcut butonları silelim...
  if High( xButonlar ) >=  Low( xButonlar )
  then for i := Low( xButonlar ) to High( xButonlar )
       do xButonlar[i].Free;

  Application.ProcessMessages;
  SetLength( xButonlar, 0 );

  i     := 0;
  Satir := 0;
  Sutun := -1;
  xAdoQuery.First;
  while NOT xAdoQuery.EOF do
  begin
    inc(i);
    SetLength( xButonlar, i );
    xButonlar[i-1] := TButton.Create(nil);
    With xButonlar[i-1] do begin
      Width   := Boy;
      Height  := Yukseklik;
      Caption := xAdoQuery.Fields[0].AsString + ': ( ' + xAdoQuery.Fields[1].AsString + ' )' ;
      Parent  := aScrollBox;
      OnClick := ButonaBasildi;

      inc(sutun);
      if aScrollBox.Width < ( SolMargin + ( Sutun * (Width + Aralik) ) + (Width + Aralik))then
      begin
        inc( Satir );
        Sutun := 0;
      end;

      Left    := SolMargin  + (Sutun * (Width  + Aralik));
      Top     := TepeMargin + (Satir * (Height + Aralik));
    end;
    xAdoQuery.Next;
  end;

end;

procedure TForm1.ButonaBasildi( aButton:TObject );
var
  strCaption : String;
begin
  if aButton = nil then
  begin
     xKatSira := 1;
     xWhere   := '';
     xGroupBy := 'GROUP BY M_Year';
  end else
  begin
    strCaption := StringReplace( TButton(aButton).Caption, '&', '', [rfReplaceAll] );
    strCaption := Trim( Copy( strCaption, 1, Pos(': (', strCaption )-1) );

    inc( xKatSira );
    if xKatSira > 4 then xKatSira := 1;
  end;

  case xKatSira of
  1: begin
       xWhere   := '';
       xGroupBy := 'GROUP BY M_Year';
       KategoriButtonOlustur( 'M_Year',    ScrollBox1 );
       UrunListele();
     end;
  2: begin
       xWhere := xWhere + ' AND M_Year = ' + QuotedStr( strCaption );
       xGroupBy := 'GROUP BY M_Runtime';
       KategoriButtonOlustur( 'M_RunTime', ScrollBox1 );
       UrunListele();
     end;
  3: begin
       xWhere := xWhere + ' AND M_Runtime = ' + QuotedStr( strCaption );
       xGroupBy := 'GROUP BY M_Lang';
       KategoriButtonOlustur( 'M_Lang',    ScrollBox1 );
       UrunListele();
     end;
  4: begin
       xWhere := xWhere + ' AND M_Lang = ' + QuotedStr( strCaption );
       KategoriButtonOlustur( '!!!ButonTemizle',    ScrollBox1 );
       UrunListele();
     end;
  end;
end;

procedure TForm1.UrunListele;
begin
  With xAdoUrunQuery do begin
    Connection := xADOConnection;
    SQL.Clear;
    SQL.Add('SELECT * FROM Movies');
    SQL.Add('WHERE 1=1');
    SQL.Add( xWhere   );
    Active := True;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  xAdoConnection.Connected := False;

  xAdoConnection.Free;
  xAdoQuery.Free;
  xAdoUrunQuery.Free;

  xDataSource.Free;
  xDataUrunSource.Free;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  KategoriButtonOlustur( '', ScrollBox1, True ); // Sadece butonları tazele
end;


@mrmarman hocam birsey kafama takildi neden adoqevery gibi komponentleri kod ile olusturuyorsunuz bunun bir nedeni varmi?
Merhaba
Haklı bir soru, şöyle açayım;

Forumlarda kod örneği verirken forma şunu koy bunu koy gibisinden yönlendirme yapınca konu dağılıyor. 

Burada koda bakarak ihtiyaç duyulan görsel olmayan bileşenler hakkında da hiç bilmeyenden en bilene kadar okunabilirlik arttığını düşünerek böyle yapıyorum.

Bir de ADO değil de ZEOS veya başka veritabanı bileşen seti kullanan olursa tek noktadan öngörü sunduğumu değerlendiriyorum. 

Görsel bileşen dışında ne kullanıyorsam bu şekilde forumlarda paylaşıyorum. 

Bir de el alışkanlığı global değilkenlerin başına mümkün olduğunca x ile ifade etmeyi tercih ediyorum. Bu sınıf ise hani F ile başlamak usulü vardır ya ona benzer şekilde
Sayfalar: 1 2 3 4