![]() |
|
Runtime Create edilen nesnenin Parent erişim sorunu - Baskı Önizleme +- Delphi Can (https://www.delphican.com) +-- Forum: Delphi (https://www.delphican.com/forumdisplay.php?fid=3) +--- Forum: Mobil Platform - FireMonkey (FMX) (https://www.delphican.com/forumdisplay.php?fid=7) +--- Konu Başlığı: Runtime Create edilen nesnenin Parent erişim sorunu (/showthread.php?tid=6001) |
Runtime Create edilen nesnenin Parent erişim sorunu - 41linea41 - 16-05-2021 Merhaba Çalışma zamanında aşağıdki ekranı oluşturuyorum.Var olan grid4x4 isimli GridPanelLayout üzerine Tcircle nesneleri create ediyorum. Fakat aşağıdaki kod ile create edilen Tcicrle nesnesinin Parent özellliğini " if sorgusu" yakalayamıyor. [attachment=1756] for I := 1 to Resimsayisi do begin grid4x4.BeginUpdate; daire:=TCircle.Create(Application); daire.Parent:=grid4x4; try daire.BeginUpdate; daire.Align:=TAlignLayout.Client; daire.Fill.Kind:=TBrushKind.Bitmap;// bkBitmap; daire.Fill.Bitmap.WrapMode:=TWrapMode.TileStretch; daire.Tag:=0; daire.Name:='Daire_4_'+IntToStr(I); daire.EndUpdate; except on E: Exception do // ShowHintFrame(frmana,'Hata:'+e.Message); end; grid4x4.EndUpdate; end; for I := 0 to ComponentCount -1 do begin if(components[I] is TCircle) then begin Listbox1.Items.Add((components[I] as TCircle).Parent.Name) ;//gridpanellayout u parent olarak görmüyor. if (Components[I] as Tcircle).Parent=grid4x4 then//if TCircle(Components[I]).Parent=grd4x4 then begin ... .... .... Bu if sorgusunu geçemiyor kod. Parent özelliğini kontrol edemiyor. İyi çalışmalar. , Runtime Create edilen nesnenin Parent erişim sorunu - mrmarman - 16-05-2021 ComponentCount ile Components üzerinden yürümek yerine ControlCount ile Controls üzerinden yürüyebilirsiniz. for I := 0 to grid4x4.ControlsCount -1 do begin if( grid4x4.Controls[I] is TCircle ) then begin Showmessage( grid4x4.Controls[I].Parent.Name ); end; end; Cvp: Runtime Create edilen nesnenin Parent erişim sorunu - savasabd - 17-05-2021 (16-05-2021, Saat: 21:23)41linea41 Adlı Kullanıcıdan Alıntı: Merhaba Çünkü siz sadece formun çocuklarını dolaşıyorsunuz, (Components[I] yazmakla Self.Components[I] yada FormX.Components[I] yazmak arasında bir fark yok) oysa TCircle'lar formun torunları oluyorlar. .Muharrem Bey'in dediği yol bence de en mantıklısı ama illa Muharrem Bey'in dediği yoldan gitmeyecekseniz şöyle bir yoldan ilerleyebilirsiniz:var daire:TCircle; i:integer; begin for I := 1 to Resimsayisi do begin grid4x4.BeginUpdate; daire:=TCircle.Create(Application); daire.Parent:=grid4x4; try daire.BeginUpdate; daire.Align:=TAlignLayout.Client; daire.Fill.Kind:=TBrushKind.Bitmap;// bkBitmap; daire.Fill.Bitmap.WrapMode:=TWrapMode.TileStretch; daire.Tag:=0; daire.Name:='Daire_4_'+IntToStr(I); daire.EndUpdate; except on E: Exception do // ShowHintFrame(frmana,'Hata:'+e.Message); end; grid4x4.EndUpdate; end; GetParent(self); end; procedure TForm1.GetParent(obj: TFmxObject); var i:integer; begin for I := 0 to obj.ChildrenCount -1 do begin if(obj.Children[I] is TCircle) then begin Listbox1.Items.Add((obj.Children[I] as TCircle).Parent.Name) ;//gridpanellayout u parent olarak görmüyor. if (obj.Children[I] as Tcircle).Parent=grid4x4 then//if TCircle(Components[I]).Parent=grd4x4 then begin // end; end; GetParent(obj.Children[i]); end; end; Runtime Create edilen nesnenin Parent erişim sorunu - ozcanm - 17-05-2021 procedure TForm1.Circle_islemleri; var i: Integer; begin for i := ComponentCount - 1 downto 0 do begin if (Components[i] is TCircle) and (TCircle(Components[i]).Parent = grid4x4) then Begin TCircle(Components[i]).Name := 'AAA'; TCircle(Components[i]).Tag := 0; // işlemler. // işlemler. // işlemler. end; end; end; Runtime Create edilen nesnenin Parent erişim sorunu - mrmarman - 17-05-2021 Merhaba. @ozcanm üstadım, TCircle'in owner eğer form olsaydı bu şekilde sonuç alınabilirdi. Burada TCircle FORM değil de Application altında create edilmiş... Kod: daire := TCircle.Create(Application);Diğer yandan bu Application değil de self olsaydı @ozcanm sizin dediğiniz şekilde olurdu... Kod: daire := TCircle.Create(self);* ComponentCount sadece bileşen tarafından sahip olduklarının (owner oldukları) listesini getirecektir. Burada aramak için OWNER eğer Application ise o zaman ComponentCount değil Application.ComponentCount olmalıydı. Components[i] yerine de Application.Components[i]..... Bu durumda da @savasabd belirttiği gibi onun child seviyesindekileri görmek için bir tane daha iç döngü açıp, elde edilen her Components[i]'nin ControlCount ile adedi bulunup Controls[j] gibisinden aramak veya TFMXObject şeklinde yürüyüp direkt child objeckt üzerine yoğunlaşmak sonuç döndürür. - Başlığı / sorunu / sorunsalı anlayamayanlar olabilir diye yukarıdaki örneği ortaya çıkarak bir senaryo aşağıda verilmiştir. - Boş bir FMX proje oluşturup, forma sadece ve sadece bir button koyup aşağıdaki kodu yapıştırın. Aşağıda birebir verilen örnek üzerinden bir yaklaşımı göreceksiniz. Burada amaç sonuç alamadığımızı ve de neyi alabildiğimizi test etmek. - CircleIslemleri procedure başına // koyarak comment altına alıp aşağıdaki exit'i kaldırınca bir de diğer türlüsünü görebilirsiniz.
Uses FMX.Objects;
Const
Resimsayisi = 16;
Rows = 4;
Cols = 4;
var
Fgrid4x4 : TGridPanelLayout;
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
daire : TCircle;
begin
// Önce yoksa bir layout kurgulayalım...
PanelLayoutOlustur();
for I := 1 to Resimsayisi do
begin
Fgrid4x4.BeginUpdate;
daire := TCircle.Create(Application); // self olmadığından ComponentCount ile çıkmaz. Application.ComponentCount ile olacaktır.
daire.Parent := Fgrid4x4;
try
daire.BeginUpdate;
daire.Align := TAlignLayout.Client;
daire.Fill.Kind := TBrushKind.Bitmap;// bkBitmap;
daire.Fill.Bitmap.WrapMode := TWrapMode.TileStretch;
daire.Tag := 0;
daire.Name := 'Daire_4_'+IntToStr(I);
daire.EndUpdate;
except on E: Exception do
// ShowHintFrame(frmana,'Hata:'+e.Message);
end;
Fgrid4x4.EndUpdate;
end;
Circle_islemleri();
Exit;
for I := 0 to Fgrid4x4.ControlsCount -1 do
begin
if( Fgrid4x4.Controls[I] is TCircle ) then
begin
Showmessage( Fgrid4x4.Controls[I].Name );
end;
end;
end;
procedure TForm1.Circle_islemleri;
var
i: Integer;
begin
for i := ComponentCount - 1 downto 0 do
begin
if (Components[i] is TCircle) and (TCircle(Components[i]).Parent = Fgrid4x4)
then
Begin
Showmessage('Bulduk'); // buraya bu örnekte hiç gelmeyecek....
TCircle(Components[i]).Name := 'AAA';
TCircle(Components[i]).Tag := 0;
// işlemler.
// işlemler.
// işlemler.
end else begin
Showmessage( Components[i].Name );
end;
end;
end;
procedure TForm1.PanelLayoutOlustur();
var
i : Integer;
begin
// Eğer yoksa örnek TGridLayout oluştur...
if NOT Assigned( Fgrid4x4 ) then begin
Fgrid4x4 := TGridPanelLayout.Create(self);
Fgrid4x4.Parent := self;
Fgrid4x4.Name := 'grid4x4';
Fgrid4x4.Position.X := 10;
Fgrid4x4.Position.Y := 100;
Fgrid4x4.Width := 300;
Fgrid4x4.Height := 300;
while Fgrid4x4.RowCollection.Count < Rows do
Fgrid4x4.RowCollection.Add;
while Fgrid4x4.ColumnCollection.Count < Cols do
Fgrid4x4.ColumnCollection.Add;
repeat
for i := 0 to Pred(Rows) do begin
Fgrid4x4.RowCollection.Items[i].SizeStyle := TGridPanelLayout.TSizeStyle.Percent;
Fgrid4x4.RowCollection.Items[i].Value := 100 / Rows;
end;
for i := 0 to Pred(Cols) do begin
Fgrid4x4.ColumnCollection.Items[i].SizeStyle := TGridPanelLayout.TSizeStyle.Percent;
Fgrid4x4.ColumnCollection.Items[i].Value := 100 / Cols;
end;
until ( Fgrid4x4.RowCollection.Items[0].Value <= 100 / Rows )
or( Fgrid4x4.ColumnCollection.Items[0].Value <= 100 / Cols ) ;
end;
end;
Cvp: Runtime Create edilen nesnenin Parent erişim sorunu - ozcanm - 17-05-2021 (17-05-2021, Saat: 09:56)mrmarman Adlı Kullanıcıdan Alıntı: Merhaba. Hocam estağfurullah, Öncelikle; Eğer, "Üstad" diye hitap edilecekse buna siz ve sizin gibi hocalarımız layıktır. Ben burada acemiyim. Acemi olmasaydım zaten yukarıda "daire := TCircle.Create(Application);" kullandığını fark ederdim. Ben genel kullanımda "daire := TCircle.Create(Self);" kullanılır düşüncesi ile tam kontrolsüz bir paylaşım yapmış oldum.
|