Gelişmiş TreeView
superco31.07.2005 - 14:49:23
S.A.

Kullanımı normal treeview gibi olan ama biraz daha gelişmiş bir treeview arıyorum.Mesela normal treeviewde bir node a sadece bir değer atayabiliyorum bunu ikiye çıkartmanın bir yolu var mı?Ayrıca savetofile yaptığımda sadece karakterler çıkıyor imageindex selectedindex gibi şeyleri kaydetmiyor.

Bu özelliklere ve fazlasına sahip olan bi Virtual Treeview var fakat oda çok zor bişey anlamadım.

Bu özelliklere sahip bildiğiniz bedava bir bileşen var mı?
 
t-hex31.07.2005 - 16:10:17
normal treeviewde bir node a sadece bir değer atayabiliyorum bunu ikiye çıkartmanın bir yolu var mı?


Her Node'un Data diye propertysi var. Bu özelliği kullanarak her node'a bir data bağlayabilirsiniz ve bu data'da istediğiniz kadar değer saklayabilirsiniz. Delphi Help'de bu tür kullanım için örnek mevcut.
Ayrıca savetofile yaptığımda sadece karakterler çıkıyor imageindex selectedindex gibi şeyleri kaydetmiyor.


Eğer sorun oluşturmayacaksa SelectedIndex gibi değerleri ayrı bir dosyaya kaydedebilirsiniz. Eğer tek dosyaya kaydetmek istiyorsanız SaveToFile metodu yerine SaveToStream metodunu kullanıp, bu streamdeki ve selectedindex + diğer istediğiniz bilgileri kaydedebilirsiniz.

Bu özelliklere ve fazlasına sahip olan bi Virtual Treeview var fakat oda çok zor bişey anlamadım.


Buna katılmıyorum, ilk bakışta çok karışık gibi geliyor ama bunun sebebi alıştığımız TTreeViewden çalışma prensibi olarak farklı olması. Takıldığınız konularda yardımcı olabilirim.

İyi çalışmalar.
 
sadettinpolat31.07.2005 - 16:31:33
delphi 7 de varolan node sınıfından yeni bir sınıf üreterek buna istediğiniz özellikleri verebilirsiniz. daha sonrada bu yeni nodeyi treeviewe ekleyebilirsiniz. marco cantu delphi 7 de vardı örneği.
 
superco31.07.2005 - 18:02:27
Öncelikle cevaplarınız için teşekkürler.

Her Node'un Data diye propertysi var. Bu özelliği kullanarak her node'a bir data bağlayabilirsiniz ve bu data'da istediğiniz kadar değer saklayabilirsiniz. Delphi Help'de bu tür kullanım için örnek mevcut.


Data propertysi pointer tipinde. şöyle bir deneme yaptığımda
procedure TForm1.Button1Click(Sender: TObject);
var
a:TTreeNode;
b:integer;
begin
for b:=0 to 10 do
begin
with TreeView1.Items.Add(nil,'ali'+IntToStr(b)) do
begin
Data:=pchar('veli'+inttostr(b));
end;
end;
end;

ShowMessage(pchar(TreeView1.Selected.data));

Mesela ali6 ya tıkladığım zaman bana göstermesi gereken veli6 yerine veli$ mesajını gösteriyor.Pointerlar hakkında hiç tecrübem yok sizin dikkatinizi çeken bişey var mı?

Buna katılmıyorum, ilk bakışta çok karışık gibi geliyor ama bunun sebebi alıştığımız TTreeViewden çalışma prensibi olarak farklı olması. Takıldığınız konularda yardımcı olabilirim.

Takıldığım konu çok basit.Node eklemek. :)

Mesela master-detail olarak ilişkilendirilmiş iki tabloyu treeview'e eklemek istediğimde:

var
a:node;
begin
tblmaster.first;
tbldetail.first;
while not tblmaster.eof do
begin
a:=treeview1.items.add(nil,tblmasterISIM.Asstring);
a.imageindex:=3;
a.selectedindex:=3;
while not tbldetail.eof do
begin
treeview1.items.addchild(a,tbldetailSoyad.AsString);
tbldetail.next;
end;
tbldetail.next;
end;

şeklinde bir kod yazıyorum,bunun basitçe Virtual Treeview karşılığı nedir?

delphi 7 de varolan node sınıfından yeni bir sınıf üreterek buna istediğiniz özellikleri verebilirsiniz. daha sonrada bu yeni nodeyi treeviewe ekleyebilirsiniz. marco cantu delphi 7 de vardı örneği.


Bahsettiğiniz örneği buldum.Eğer Marco Cantu'nun kitabı olmayan varsa bahsedilen örnek kendi sitesinde var(05\CustomNodes)
http://www.marcocantu.com/md7/md7code.zip


İkinizede tekrar teşekkür ederim.
 
t-hex31.07.2005 - 18:53:57
Nodelara data eklerken PChar kullanmayın çünkü her node'da datanın aynı boyutta olması lazım. onun yerine

type
TNodeData = class
Adi :String;
Soyadi : String;
end;


buna benzer bir sınıf tanımlayın. Daha sonra

node.Data := TNodeData.Create;
with TNodeData(node.Data) do begin
Adi := 'adi';
Soyadi := 'soyadi';
end;


gibi bir kodla data bağlayabilirsiniz. hatta alan sayısını istediğiniz kadar artturabilirsiniz. Yalnız bu yarattığınız sınıfları hafızadan silmeyi atlamamnız lazım. Bunu da TreeView'in OnDelete olayını kullanarak yapabilirsiniz.


procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
if assigned(Node.Data) then begin
TNodeData(Node.Data).Free;
Node.Data:=nil;
end;
end;


Virtual Tree Viewde verdiğiniz örnektekine benzer AddChild fonksiyonu var.

VAR
VTNode : PVirtualNode;
begin
VTNode := VirtualStringTree1.AddChild(VirtualStringTree1.RootNode);
VirtualStringTree1.AddChild(VTNode);
end;


ama bu kullanım önerilen yöntem değil. Onun yerine OnInitNode, OnInitChildren olaylarına kod yazarak bu işin yapılması isteniyor.

Mesela, master tablodaki kadar kayıt eklemek için

VirtualStringTree1.RootNodeCount := tblMaster.RecordCount;

kullanabilirsiniz. Bu durumda master tabloda kaç kayıt varsa onun kadar node eklenecek ve hemen onInitNode olayına yazdığınız kod çağrılacak. Örneğin

procedure TForm1.VirtualStringTree1InitNode(Sender: TBaseVirtualTree;
ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
begin
// bu node'un childnode'u olduğunu berlitmek için
InitialStates := InitialStates + [ivsHasChildren];
end;
procedure TForm1.VirtualStringTree1InitChildren(Sender: TBaseVirtualTree;
Node: PVirtualNode; var ChildCount: Cardinal);
begin
ChildCount := 5;
end;


yazın ve açıldıkça açıldığını görün :)
 
superco31.07.2005 - 19:54:23
Nodelara data eklerken PChar kullanmayın çünkü her node'da datanın aynı boyutta olması lazım. onun yerine

type
TNodeData = class
Adi :String;
Soyadi : String;
end;


buna benzer bir sınıf tanımlayın. Daha sonra

node.Data := TNodeData.Create;
with TNodeData(node.Data) do begin
Adi := 'adi';
Soyadi := 'soyadi';
end;


gibi bir kodla data bağlayabilirsiniz. hatta alan sayısını istediğiniz kadar artturabilirsiniz. Yalnız bu yarattığınız sınıfları hafızadan silmeyi atlamamnız lazım. Bunu da TreeView'in OnDelete olayını kullanarak yapabilirsiniz.


procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
if assigned(Node.Data) then begin
TNodeData(Node.Data).Free;
Node.Data:=nil;
end;
end;




Hocam node.data örneği için teşekkürler.İşimi gördü :)

Lakin önceden tavsiye ettiğiniz stream nesnesiyle uğraşırken TStream'de savetofile gibi bir metodunu göremedim.Helpten baktığımda savetofile metodu olan bi TMemoryStream vardı bende

var
a:TMemoryStream;
begin
a:=tMemoryStrem.create;
Treeview1.SaveToStream(a);
a.SaveToFile('c:\stream.txt');
a.free;

şeklinde bişeyler yazdım.Ama treeview'in kendi savetofile metodundan bir farkı yok direk text değerlerini saklıyor.Sanırım stream yerine memory stream kullandığımdan ötürü oldu.Tstream nesnesini direk diske nasıl kaydedebilirim.(Programcılıkta yeni sayılırım daha önce tstream kullanmamıştım.)

Virtual Tree Viewde verdiğiniz örnektekine benzer AddChild fonksiyonu var.

VAR
VTNode : PVirtualNode;
begin
VTNode := VirtualStringTree1.AddChild(VirtualStringTree1.RootNode);
VirtualStringTree1.AddChild(VTNode);
end;


ama bu kullanım önerilen yöntem değil. Onun yerine OnInitNode, OnInitChildren olaylarına kod yazarak bu işin yapılması isteniyor.

Mesela, master tablodaki kadar kayıt eklemek için

VirtualStringTree1.RootNodeCount := tblMaster.RecordCount;

kullanabilirsiniz. Bu durumda master tabloda kaç kayıt varsa onun kadar node eklenecek ve hemen onInitNode olayına yazdığınız kod çağrılacak. Örneğin

procedure TForm1.VirtualStringTree1InitNode(Sender: TBaseVirtualTree;
ParentNode, Node: PVirtualNode;
var InitialStates: TVirtualNodeInitStates);
begin
// bu node'un childnode'u olduğunu berlitmek için
InitialStates := InitialStates + [ivsHasChildren];
end;
procedure TForm1.VirtualStringTree1InitChildren(Sender: TBaseVirtualTree;
Node: PVirtualNode; var ChildCount: Cardinal);
begin
ChildCount := 5;
end;


yazın ve açıldıkça açıldığını görün :)

Hocam göremedim Embarassed Biraz daha çalışmam lazım Virtual Treeview üzerine.

Tekrar teşekkürler hocam.

Not:Bu arada Virtual Treeview baya gelişmiş bir bileşen.Delphi'de olmayan birçok bileşenin(Object inspector,Quantumgrid tarzı grid vs..) yerine geçebilecek kadar ayrıntılı.
 
t-hex31.07.2005 - 20:47:28
TStream sınıfı TFileStream,TMemoryStream,TStringStream gibi sınıfların atasıdır ve abstract metodlar içerir, o yüzden direk TStream kullanamazsınız. Bu durumda sizin kullanmanız gereken TMemoryStream.

Ama sizin sorununuz TreeView'in her şeyi kaydetmemesi. Zaten help içerisinde de SaveToFile veya SaveToStream metodlarını kullandığınızda kaydedilenin sadece text olacağı, bağladığınız data ve benzeri bilgilerin kaydedilmeyeceği yazıyor. Bu yüzden en mantıklısı bu kaydetme işini yapacak kodu sizin yazmanızdır.

var
node : TTreeNode;
begin
node := TreeView1.Items.GetFirstNode;
while node <> nil do begin
NodeKaydet(Node); // bu prosedür nasıl kaydetcekseniz öyle yazılmalı.
node := node.GetNext;
end;

bu yapıdaki bir kodla TreeViewdeki bütün nodelara ulaşabilirsiniz.

Kolay gelsin.
 
superco31.07.2005 - 20:59:22
Teşekkürler hocam.
 
NOT : Bu sayfa google'un siteyi indekslemesi içindir. www.delphiturkiye.com/forum/ adresini kullanınız!
1998-2006 www.delphiturkiye.com