You don't need to load all the data into the tree. You can use the 'virtualness' of the tree. Here's how I would do it.
You don't need to load all the data into the tree. You can use the 'virtualness' of the tree. Here's how I would do it.
Set the RootNodeCount of the tree to the number of records in CustomerObjectList: vstree. RootNodeCount := CustomerObjectList. Count; Then, in the OnInitChildren event, set the child count of level 0 nodes to the number of properties you want to display: procedure TfrmMain.
VstreeInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); begin if Sender. GetNodeLevel(Node) = 0 then begin Sender. ChildCountNode := 4; // Comment this out if you don't want the nodes to be initially expanded Sender.
ExpandedNode := TRUE; end; end; Now, just retrieve the correct data in the OnGetText event. Procedure TfrmMain. VstreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); begin if Column GetNodeLevel(Node) = 0 then CellText := CustomerObjectListNode.Index.
Name else if Sender. GetNodeLevel(Node) = 1 then begin case Node. Index of 0: CellText := CustomerObjectListParent.Node.Index.
Sex; 1: CellText := CustomerObjectListParent.Node.Index. Age; 2: CellText := CustomerObjectListParent.Node.Index. Hair; 3: CellText := CustomerObjectListParent.Node.Index.
City; end; // of case end; end; You'll probably want to add in some more range checking, just in case. Hope this helps.
Thank you for the great information. I checked it out but I could not get the childnodes to populate - vstreeInitChildren() doesn't seem to fire. – TheSteven Nov 6 at 17:20 That's what you get for not testing :) I've updated the code and tested it (changed InitChildren to InitNode and altered the event code).
Works find now. – norgepaul Nov 6 at 21:15 I came up with a different fix - but yours is simpler and more elegant! In either case I still have to cast my object in order to retrieve the data as in >> CellText := TCustomerNode(CustomerObjectListNode.
Index). Name .Create. As a rule of thumb, you rarely need to store anything in the tree records if you already have the data elsewhere.
– norgepaul Nov 7 at 8:05.
The only thing I've been able to get working is to link the whole object in again for each child and then just display the field I need - but it just feels so wrong... Suggestions/feedback much appreciated. You have to do that because you are mixing levels. Your tree is set up to expect object instances at every level.
But you instance list only has objects at the main level and object properties at the sub level. To all intents and purposes there is nothing wrong with that. If you really want to avoid it, you would have to work with a composite pattern where an object owns a list of attributes which themselves are objects again.
Would work, but would also make working with your classes a heck of lot messier. Though you could always provide access to the owned attributes by using indexed properties. TSomeObject = class(TObject) private MyObjects: TList; protected function GetStringProperty(const aIndex: Integer): string; public property Name: string index 1 read GetStringProperty; end; This is known as an Entity Attribute Value model.( The EAV/CR Model of Data Representation ) It provides flexibility but does have drawbacks, especially if you were to structure your database in a similar manner.
Thanks for info of Entity Attribute Value model - will check it out in more detail late, but a least for now I think its overkill for what I need. – TheSteven Nov 5 at 0:20.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.