Recent

Author Topic: [SOLVED] add new item in VirtualTreeView!?!  (Read 7543 times)

majid.ebru

  • Sr. Member
  • ****
  • Posts: 494
[SOLVED] add new item in VirtualTreeView!?!
« on: February 16, 2018, 11:27:32 am »
i upgraded Lazarus to 1.8.0RC5

now i have problem and i  have many questions ?!?!?

i should use VirtualTreeView.

but i can't add new item root and new item child?!?!

i see demo file and it has this code :

Code: Pascal  [Select][+][-]
  1.   with VST1 do
  2.   try
  3.     Start := GetTickCount;
  4.     case (Sender as TButton).Tag of
  5.       0: // add to root
  6.         begin
  7.           Count := StrToInt(NodeCountEdit.Text);
  8.           RootNodeCount := Integer(RootNodeCount) + Count;
  9.         end;
  10.       1: // add as child
  11.         if Assigned(FocusedNode) then
  12.         begin
  13.           Count := StrToInt(NodeCountEdit.Text);
  14.           ChildCount[FocusedNode] := Integer(ChildCount[FocusedNode]) + Count;
  15.           Expanded[FocusedNode] := True;
  16.           InvalidateToBottom(FocusedNode);
  17.         end;
  18.     end;
  19.     Label1.Caption := Format('Last operation duration: %d ms', [GetTickCount - Start]);
  20.     Label3.Caption := Format('Nodes in tree: %d', [VST1.TotalCount]);
  21.   finally
  22.     Screen.Cursor := crDefault;
  23.   end;
  24.  

when i use above code i just have "..." (image 1)

but i want to change text of items?
i use this code to set text item:
Code: Pascal  [Select][+][-]
  1. FormMain.TV_T3_1.ItemS[0].Text := Str1

how can i set fouce or select , item 'n' ?
i use this code in treeview to select item :
Code: Pascal  [Select][+][-]
  1. FormMain.TV_T3_1.ItemS[j].Selected:= True;

how can i add child item?
i use this code to add child item :
Code: Pascal  [Select][+][-]
  1. FormMain.TV_T3_1.Items.AddChild(FormMain.TV_T3_1.Selected,Str1);

How can i check Level of item?
i check level of item wiht this code:
Code: Pascal  [Select][+][-]
  1. if(TV_T3_1.Selected.Level = 1 )then begin

how can i count of items?
i use this code:
Code: Pascal  [Select][+][-]
  1. TV_T3_1.Items.Count - 1

how can i get text of selected item??
i use this code:
Code: Pascal  [Select][+][-]
  1. E_T5_2.Text := TV_T3_1.Selected.Text

how can i get index of selected item??
Code: Pascal  [Select][+][-]
  1.  i:= TV_T3_1.Selected.Index

how can i change color of row items?
Code: Pascal  [Select][+][-]
  1. TV_T3_1.SelectionColor := clBlack ;

i don't know what this is:  :-[
Code: Pascal  [Select][+][-]
  1. TV_T3_1.Items.Item[0].Selected := True;


thank you
« Last Edit: April 23, 2018, 05:01:41 am by majid.ebru »

torumyax

  • New Member
  • *
  • Posts: 34
Re: add new item in VirtualTreeView!?!
« Reply #1 on: February 17, 2018, 11:38:35 am »
Hello,

I'm no expert, but I think it is a good start to follow this step by step instruction on the wiki page.

http://wiki.freepascal.org/VirtualTreeview_Example_for_Lazarus

Cheers.

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: add new item in VirtualTreeView!?!
« Reply #2 on: February 17, 2018, 02:35:47 pm »
Yes, this tutorial is VERY good. Read it, absolutely.

A few notes which came to my mind when reading the questions

Quote
but i want to change text of items?
i use this code to set text item:
Code: Pascal  [Select][+][-]
  1.     FormMain.TV_T3_1.ItemS[0].Text := Str1
  2.  
VirtualTreeView is called "virtual" because it does not contain any data. It is just the container for a hierarchical relationship between nodes. Data are provided by means of events or external data structures. Therefore you cannot change the Text in an item, you must change the text in the associated data structure.

Also, in above code snipped, you are referencing nodes by means their index. This is possible, yes, but it is a very ineffecient way. Better to follow the parent-child-sibling relationships. The VST provides methods for finding all these nodes for a given node.

Code: [Select]
how can i count of items?What do you mean as "count"? Count of the children of a node (--> VST.ChildCount[node]), Count of the children and all their children etc (--> node^.TotalCount), count of all nodes in the tree (--> VST.TotalCount); node is a PVirtualNode here, e.g. VST.FocusedNode. I am not 100% sure about this, but I think normally the tree does not even know how many nodes it has in total because it would have to open all nodes. But this is just the reason for the speed of VST: it loads only the nodes when they are needed, and querying the count would require the tree to load all nodes. Since the VST can handle with millions if nodes, this would be very inefficient. Do you really need the Count?

Code: [Select]
how can i set fouce or select , item 'n' ?Again: what is "n"? Of all nodes? Or the index within the children of a given node? But better to stop thinking of n, better think of the nodes directly, that's the way the tree is designed. If you mean the n-th node in the top level, e.g. you can do this to find the node (not tested..):
Code: Pascal  [Select][+][-]
  1. function FindNthTopLevelNode(VST: TVirtualStringTree; n: Integer): PVirtualNode);
  2. begin
  3.   Result := VST.GetFirstChild(VST.RootNode);
  4.   while (n > 0) and (Result <> nil) do begin
  5.     Result := VST.GetNextSibling(Result);
  6.     dec(n);
  7.   end;
  8. end;
Once you found the node you can select/focus it this way
Code: Pascal  [Select][+][-]
  1. var node: PVirtualNode;
  2.   VST.FocusedNode := node;
  3.   VST.Selected[node] := true; // both needed!

Quote
how can i get text of selected item??
You must get the data associated with the selected node. The data are a user-defined structure, usually a record or a class, and you know how to retrieve the text from it. Assuming that data are a record as defined in the tutorial then you can do this:

Code: Pascal  [Select][+][-]
  1. type
  2.   PTreeData = ^TTreeData;
  3.   TTreeData = record
  4.     Column0: String;
  5.     Column1: String;
  6.     Column2: String;
  7.   end;
  8.  
  9.   function GetNodeText(VST: TVirtualStringTree; ANode: PVirtualNode): String;
  10.   var
  11.     data: PTreeData;
  12.   begin
  13.     data :=PTreeData( VST.GetNodeData(ANode));
  14.     if data = nil then
  15.       Result := ''
  16.     else
  17.       Result := data^.Column0;
  18.   end;

etc, etc.

Trying to use the VirtualStringTree requires a steep learning curve. It is much more than just reading a short forum answer. I urge you to read the tutorial recommended in the previous post. You may also seek for more in the internet, e.g. https://www.youtube.com/watch?v=o6FpUJhEeoY.



majid.ebru

  • Sr. Member
  • ****
  • Posts: 494
Re: add new item in VirtualTreeView!?!
« Reply #3 on: February 22, 2018, 07:26:34 pm »
Hi and thank you

i almost see and read about VirtualTreeView.

i write these codes and i solve many of my problems?!?!

Code: Pascal  [Select][+][-]
  1. type
  2.   PMyNode = ^TMyNode;
  3.   TMyNode = record
  4.     Col1,Col2,Col3 :String;
  5.   end;
  6.  
  7.   const
  8.     szMyNode = sizeof(TMyNode);                                    
  9.  

Onclick:
Code: Pascal  [Select][+][-]
  1. procedure TFormMain.VSTClick(Sender: TObject);
  2. var
  3.   Node: PMyNode;
  4. begin
  5.   with(FormMain.VST)do
  6.     Node := GetNodeData(FocusedNode);
  7.   L_P3_3.Caption :=  Node^.Col1;
  8.   L_P3_4.Caption :=  Node^.Col2;
  9.   Panel4.Caption :=  Node^.Col3;
  10. end;

onGetDataSize :
Code: Pascal  [Select][+][-]
  1. procedure TFormMain.VSTGetNodeDataSize(Sender: TBaseVirtualTree;
  2.   var NodeDataSize: Integer);
  3. begin
  4.   NodeDataSize := szMyNode;
  5. end;

onGetText:
Code: Pascal  [Select][+][-]
  1. procedure TFormMain.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  2.   Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
  3. var
  4.   LMyNode : PMyNode ;
  5. begin
  6.   LMyNode  := Sender.GetNodeData(Node);
  7.   case(Column)of
  8.     0: CellText:= LMyNode^.Col1;
  9.     1: CellText:= LMyNode^.Col2;
  10.     2: CellText:= LMyNode^.Col3;
  11.   end;
  12. end;

and when i want to add child , ican't to that?

i use this code for add child:
Code: Pascal  [Select][+][-]
  1. .
  2. .
  3. .
  4. var
  5.   LMyNode : PMyNode;
  6. .
  7. .
  8. .
  9. FormMain.VST.BeginUpdate;
  10. .
  11. .
  12. .
  13. with(FormMain.VST)do
  14.     LMyNode:= GetNodeData(AddChild(nil,nil));
  15. .
  16. .
  17. .
  18. LMyNode^.Col1 := FieldS[15]{Name}.Text;
  19. LMyNode^.Col2 := FieldS[14]{Code}.Text;
  20. LMyNode^.Col3 := FieldS[10]{Level}.Text;
  21. .
  22. .
  23. .
  24.  
i should  create tree from data bank but i can't

can help me

please see Image -> VST02

also i can't change color of Item text?
« Last Edit: February 22, 2018, 08:44:45 pm by majid.ebru »

wp

  • Hero Member
  • *****
  • Posts: 11853
Re: add new item in VirtualTreeView!?!
« Reply #4 on: February 23, 2018, 12:02:58 am »
If your DB-Table contains an ID and ParentID field then, before adding the new node, you must always seek the node which has the same ID as the parentID in the record. This will be the parentnode of the new node.

To change the font color you can hook into the OnPaintText event.

Don't forget to remove the strings of the node data record in the OnFreeNode event - otherwise you'll have a memory leak.

I can remember how hard it was to write my first virtual db-treeview. To help you I took some time an write the attached demo, which is similar to what you need. Carefully look at the code, and try to understand everything. Also look at the properties - I changed a lot in the Object Inspector.

In the other attachment you can find another tutorial which I once had found somewhere in the internet and is even better than the wiki page because it gives more explanations.

BTW, in the Online Package Manager you can find a package VirtualDBTreeViewEx with which you probably can achieve the same without any code - but I never used it, though. But the learning experience is better doing it the hard way!

majid.ebru

  • Sr. Member
  • ****
  • Posts: 494
Re: add new item in VirtualTreeView!?!
« Reply #5 on: February 28, 2018, 01:40:31 pm »
Hi

@wp   thank you very much  :-* :-* :-*

I eventually managed to add items to VirtualTreeView
« Last Edit: February 28, 2018, 06:49:52 pm by majid.ebru »

majid.ebru

  • Sr. Member
  • ****
  • Posts: 494
Re: add new item in VirtualTreeView!?!
« Reply #6 on: February 28, 2018, 06:45:25 pm »
Hi

how can I get node wicth i right-Click on node VirtualTreeView ?

i don't know that i can say my question in this topic or i should say in another topic?!?!
.
.
.
i have a VirtualTreeView (VST) and i set

Code: Pascal  [Select][+][-]
  1.  
  2. (VirtualTreeView) VST -> TreeOptions -> SelectionOptions -> toRigthClickSelect -> set True
  3.  

and i write :

Code: Pascal  [Select][+][-]
  1. procedure TFormMain.VSTMouseDown(Sender: TObject; Button: TMouseButton;
  2.   Shift: TShiftState; X, Y: Integer);
  3. var
  4.   Node: PMyNode;
  5. begin
  6.   with(FormMain.VST)do begin
  7.     Node := GetNodeData(FocusedNode);
  8.     if (ssRight in Shift) and (Node <> nil) then  begin
  9.       VSTClick(FormMain.VST);
  10.       ShowMessage('Node Selected Text : '+Node^.Col1);
  11.     end;
  12.   end;
  13. end;

i left-click on VST and i select "00B1" then i rigth-click on "B4". but i  can't select "B4"?

i want when i Rigth-Click on "B4" , at first  "B4" selected(or FocusedNode) then "procedure TFormMain.VSTMouseDown" runs

but when i Rigth-Click on "B4" , at first  "procedure TFormMain.VSTMouseDown" runs then "B4" selected(or FocusedNode) ??

how can I get node wicth i right-Click on node VirtualTreeView ?

help (or guide ) me , please

Thank you

balazsszekely

  • Guest
Re: add new item in VirtualTreeView!?!
« Reply #7 on: February 28, 2018, 07:09:33 pm »
Use the combination of the following two events: OnMouseDown and OnFocusChanged. Something like this:
Code: Pascal  [Select][+][-]
  1.  TForm1 = class(TForm)
  2.   //...  
  3.   private
  4.     FRightClickNode: PVirtualNode; //<--add this
  5.   public
  6.  
  7.   end;
  8.  
  9. //...
  10.  
  11. procedure TForm1.VSTMouseDown(Sender: TObject;
  12.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  13. begin
  14.   if (ssRight in Shift) then
  15.     FRightClickNode := VST.GetNodeAt(X, Y);
  16. end;
  17.  
  18. procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
  19.   Column: TColumnIndex);
  20. begin
  21.   if FRightClickNode = Node then
  22.   begin
  23.     //only nodes selected by right click
  24.     ShowMessage(VST.Text[Node, Column]);
  25.   end;
  26. end;            

majid.ebru

  • Sr. Member
  • ****
  • Posts: 494
Re: add new item in VirtualTreeView!?!
« Reply #8 on: March 02, 2018, 05:11:13 am »
Use the combination of the following two events: OnMouseDown and OnFocusChanged. Something like this:
Code: Pascal  [Select][+][-]
  1.  TForm1 = class(TForm)
  2.   //...  
  3.   private
  4.     FRightClickNode: PVirtualNode; //<--add this
  5.   public
  6.  
  7.   end;
  8.  
  9. //...
  10.  
  11. procedure TForm1.VSTMouseDown(Sender: TObject;
  12.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  13. begin
  14.   if (ssRight in Shift) then
  15.     FRightClickNode := VST.GetNodeAt(X, Y);
  16. end;
  17.  
  18. procedure TForm1.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
  19.   Column: TColumnIndex);
  20. begin
  21.   if FRightClickNode = Node then
  22.   begin
  23.     //only nodes selected by right click
  24.     ShowMessage(VST.Text[Node, Column]);
  25.   end;
  26. end;            

@ GetMem  thank you

but i have a problem.

when i right-click on "B4" and then i right-click on "B3" , i see "ShowMessage(VST.Text[Node, Column]);" and everything is ok

but when i left-click on "B4" and then i rigth-click on "B4" ,i don't see "showmessage", i don't have codes in "onMouseDown" event?

balazsszekely

  • Guest
Re: add new item in VirtualTreeView!?!
« Reply #9 on: March 02, 2018, 06:33:40 am »
@majid.ebru
Quote
but i have a problem.
when i right-click on "B4" and then i right-click on "B3" , i see "ShowMessage(VST.Text[Node, Column]);" and everything is ok
but when i left-click on "B4" and then i rigth-click on "B4" ,i don't see "showmessage", i don't have codes in "onMouseDown" event?
Please try attached demo.

majid.ebru

  • Sr. Member
  • ****
  • Posts: 494
Re: add new item in VirtualTreeView!?!
« Reply #10 on: March 02, 2018, 07:23:04 am »
@ GetMem  thank you

it works :-*
« Last Edit: April 09, 2018, 10:13:14 am by majid.ebru »

 

TinyPortal © 2005-2018